Switch The Legend of Zelda: Tears of The Kingdom Yuzu Emulation Guide (2K/4K+60FPS Update)

If you haven't used Yuzu emulator before, please read Switch Emulation With Yuzu first.

Update firmware

You MUST have firmware version 16.0.1 or newer to run TOTK. Note: prod.keys is related to firmware's major version. For example, prod.keys for 15.x firmware won't work on 16.x firmware. If you don't know how to install firmware, read Switch Emulation With Yuzu.

Fix the loading issue

Yuzu can load BOTW smoothly without any tweeks. However, TOTK stuck at the loading screen.

The solution is to download and install this mod: TOTKYuzuFix.zip. If you don't know how to install MOD, read Switch Emulation With Yuzu.

Then you should be able to load and play the game. I have an AMD RX6700 GPU, and it gives me stable 30 fps.

Fix graphic glitches (cloud pixels)

The first time you jump from the sky island and dive into the open world, you will see the weird cloud which looks like some QR code… The reason is that Yuzu hasn't compiled and loaded Vulkan shaders properly.

Here are two solutions:

  1. Save the game and restart. Everything should look fine.
  2. Download and install pre-compiled Vulkan shaders from the internet.

You may also see some frame drops when exploring new areas. This is also because of Vulkan shader compiling. As you play more, the game will become smoother.

Install native 2K/4K+60FPS MODs

TOTK's graphics is even more blurry than BOTW. Limited by low power of Switch, TOTK internally render to 560p~680p resolution and up-scale to 720p/1080p with FSR. So it looks worse than native 720p/1080p games. If you use Yuzu emulator's 2x resolution, the game was up-scaled twice to 2K/4K, which looks as bad as its original resolution.

However, with 2K/4K+60FPS MODs, we can make the game runs in native 2K/4K, and 40~60FPS. This is a huge boost of experience! Checkout the difference below:

Download MODs:

If you don't know how to install MOD, read Switch Emulation With Yuzu.

After MODs installed, configure the game in Yuzu (context menu -> properties). Make sure to set the following settings:

  • Add-ons tab
    • Check all installed MOD.
  • System
    • Check Unsafe extended memory layout (8GB DRAM), then we can use 8GB RAM, to render more details.
  • Graphics
    • Resolution set to 1X, we use native 4K, not fake 4K through FSR.
    • Anti-Aliasing Method set to None, to improve performance. (Optional)

Save and restart the game. You will run TOTK in 2K/4K+60FPS. If your GPU is not powerful enough, you might get only 40~50FPS. But that is still much better than the original 30FPS experience!

Front-end Build Tools in 2023

The Standard

When we say a front-end build tool, we mean:

  • It is able to build production assets.
  • It has a dev server with HMR.
  • It supports common technology like Sass, LESS, CSS modules, code splitting.
  • It supports plugins.
  • It does NOT restrict UI framework to use or bundle unnecessary application runtime, like Redux.

Ready for production

When we say a build tool is ready for production, we mean:

  • It is popular. (>100k weekly downloads from npm)
  • It is actively maintained. (at least 1 release in last 6 month)
  • It has no critical performance or compatibility issues.

Vite 4

Vite 4 is based on esbuild (written in Go) and Rollup. It adopts un-bundled dev server for faster HMR and bundled dependencies for faster cold booting.

Vite 4 has a new swc based React plugin @vitejs/plugin-react-swc to replace the old babel based plugin. This makes React Fast Refresh 20x faster than before. It is still one of the fastest solutions.

Vite is easy to use. You can start without any configuration. When need customization, the user document is detailed and helpful. Writing plugins, or even create your own build tools based on Vite, is relatively easy. (Thanks to Vite's JS API design)

Vite has a large community and eco-system, making it easier to find plugins for your needs and solutions for your questions.

Vite 4 isn't perfect:

  • In my own tests, Vite 4's pre-bundling is much slower than Vite 2, and not comparable to esbuild. See #8850. Luckily, this only affect cold start of dev server, and Vite team is working on a fix.

Parcel 2

Parcel 2 is based on a collection of efficient tools written in Rust, like swc, Parcel CSS, to achieve better performance than Webpack 5. Parcel 2, which default configuration, has overall performance in the middle of Vite 4 and Webpack 5. But you can increase performance by enable some experimental features, like swc minification.

If HMR and build performance is your main concern (code base with millions of lines of source code), Parcel 2 is the best choice for you.

Parcel 2 isn't perfect:

  • For React (still CJS only in 2023!) projects, you need to polyfill node built-in modules, like process. In theory, parcel will install these polyfill packages automatically when needed. However, it may not work when you use pnpm rather than npm.
  • Plugin eco-system is still small.
  • JS API is not as complete as Vite. When you create your own build tools, Vite is probably a better choice than Parcel as a basement.

Webpack 5

Webpack is still the most popular choice, with the most complete features and largest eco-system.

Webpack is slow, but you can make it faster by using plugins and loaders:

Observation list

Some exciting & promising projects in early stage.

Rspack

A webpack alternative written in Rust. Created by ByteDance.

Not Included

Turbopack

High performance bundler for Next.js, support SSR. Unqualified because it only works in Next.js framework (for now).

UMI

Build tool from Ant Group. Unqualified because it is heavily customized, only supports React, and bundled too many runtime, like Redux.

ICE

Build tool from Alibaba. Unqualified because it is heavily customized, only supports React, and bundled too many runtime, like Redux.

Create React App

React's official build tool. Unqualified because it only supports React and doesn't support configuration and plugins.

Performance Benchmark

dev server cold startdev server warm startproduction build
rspack 0.1.12.2s2.0s1.4s
vite 4.2.14.3s1.3s6.5s
parcel 2.8.313.0s1.3s15.7s
webpack 5.76.214.2s14.2s15.8s

More details, see https://github.com/guoyunhe/front-end-build

Technology Trends

Technology that can potentially make build tools better and faster in future.

Node.js Module Format: Native vs WASM vs JS

Here are more and more Node.js modules written in native language, like Rust and Go. However, written in native languages doesn't mean native performance. It depends on the type of output modules: native, WASM or JS. Without threading, performance from highest to lowest is native > WASM > JS. JS and WASM are single threaded by default, unless you use cluster mode (I haven't see successful story in front-end builders). Native modules, like esbuild, can make full use of multi-threading to achieve even better performance.

However, native modules must be compiled individually for each platform, and it doesn't run in browsers. On the contrary, JS and WASM are "compile once, run everywhere", which is much easier for distribution.

In practice, native modules are mainly used in core components with heavy loads, like rspack, swc, esbuild. Plugins etc. are still written in JS. WASM is not as popular as the other two. One use case is swc plugin development.

Faster Sass compiler

Sass' old node-sass compiler was deprecated. The new official Dart Sass compiler is confusing:

  • The native build has no way to be integrated into existing Node.js tool chains, unless you use Node.js' exec function (not recommended in production usage).
  • The JavaScript build is 4x to 30x slower than node-sass (depend on project size). When your build tool use Sass in a wrong way, the speed can be worse. See issue #1557 and #1534

This is a deal breaker for production projects that heavily use Sass. Many projects choose to stick with deprecated node-sass compiler.

Here are new Sass compilers written in Rust:

  • grass. It only released as WASM, not native module, which doesn't have much advantage over Dart Sass (JS).
  • rsass. Unfortunately, it doesn't support Node.js API, which makes it difficult to integrate with existing front-end eco-system.

Faster TypeScript checker

TypeScript is slow cause it is written entirely in JS. Luckily, we usually don't need to check types when building a front-end project. Babel, esbuild or swc will simply ignore all types. However, if your project has strict QA and you have to run tsc, your CI workflow will be slow down even if your project is small (10k lines) or medium size (100k lines).

Re-implementation of TypeScript has become a popular idea. We have seen some attempts:

Work As Front-end Developer In Finland

This is only my own story. I hope you find something helpful. But be aware the information can be out-dated and a little subjective.

Continue reading →

position: fix not working? Check transform

In CSS, many position/layout properties are context-aware. For example, position: absolute; only works if the desired parent has position: related/absolute/fixed;. However, position: fixed; is very simple. It is always related to window, barely affected by parent container. But, I stuck in this small issue:

transform:scale(1);
position:fixed; right:10px; bottom:10px;

This is strange, I have position: fixed; but why it doesn't work?

So I checked its parent elements one by one and found the modal library left a transform: scale(1);. It doesn't make any visual difference and seems a side effect of animation. In browsers' implementation, even if scale(1) and translateX(0) don't make any sense, the transform property will recreate a coordinate system. As result, position:fixed of inner elements will not be related to window, but the transform element.

The solution is simple, change transform: scale(1) to transform: unset. In practice, avoid using transform in large containers, like a sidebar or modal. If you need it, make sure here is no position: fixed inside, such as some popups.

Integrate Crowdin To RetroArch

RetroArch project uses *.h files to store translation strings. Here aren't any tools to make the translation process easier. When source strings changed, you have to manually review the changes, locate and update translation strings. It is a hard work. As a big fan of RetroArch, I was thinking if it can be improved with modern i18n platforms.

Continue reading →

HTML vs. JavaScript Input Validation

If you want to validate a form input and so it only accepts integers, here is an easy way in HTML5:

<input type="number" pattern="[0-9]*" />

However, users can still type something invalid:

  1. In Firefox, you can basically type anything, like "fsielfs".
  2. In Chrome, you can type numbers with dots, like "1..2.2.2".
Continue reading →

Create React WebExtension for Firefox and Chrome

We will create a React app and turn it into a Firefox/Chrome extension.

Continue reading →

Code Journey #11

Highlights for the last month: HiDPI bug fixes and emulator packaging.

KDE:

  • Kompare HiDPI [patch]
  • Filelight HiDPI [patch]
  • KSysGuard HiDPI, except the sensor graphy [patch]
  • Font manager HiDPI [patch]
  • enablefont and disablefont icon for font manager [patch]
  • KWallet HiDPI [patch]
  • KWin HiDPI [patch]
  • Krita splash screen HiDPI [patch]
  • Kate/KonsolePart dual screen rendering issue [bug] [patch]
  • Spectale Dual Screen issue [bug] [patch]

openSUSE:

  • Update python-PyMuPDF package and fix linking issue
  • Update arcanist package and submit to Factory [request]
  • Submit PCSX2 package to Factory [request]
  • Update retroarch package to work out-of-box [request 1] [request 2]
  • Create retroarch-assets package [request]
  • Create retroarch-joypad-autoconfig package [request]
  • Create libretro-core-info package [request]
  • Create libretro-database package [request]
  • Create libretro-mame2000 core package [request]
  • Create libretro-genesis-plus-gx core package [request]
  • Create libretro-flycast core package [request]
  • Create libretro-yabause core package [request]

openSUSE Conference 2019 @Nuremberg

Participating openSUSE Conference is one of my dream. I always cannot find a time to do it until I made my mind to leave all other stuff. Thank my company for sponsoring my flight.

Munich Central Station

I have visited Munich for many times. It is familiar place but the memory is so far and mixed with smiles and tears. Feel a bit sad.

The conference started at 10am. When I arrived Nuremburg by train, it already afternoon.

Here we are
Like these lovely houses

The city is not big. Streets are wide, straight and clean, so I can easily find my way. I think when I retired, I will look for a similar place for the rest of my life.

Beer garden and geeks' talking
Tech report

It is a three day event. Everyday here are tech talks, mostly about containers, Kubernetes. I am not interested in though… There are also some tough topic, like the plan of openSUSE Foundation (SUSE doesn't seem liking the idea…).

Funny things:

  1. openSUSE and Fedora sponsor each other. Fedora developers made a GitLab replacement and even made a demo for openSUSE.
  2. Kernel of Leap and SLE is old. They need to backport new kernel patches. And the amount is tens of thousands. Usually you apply patches in a sequence. But they find a way to parallel apply patches in several seconds.
  3. A few openSUSE's servers run Fedora and Debian.
Lounge
Summer feeling!
The long table meeting

It is interesting that someone recognized I made the opi tool. Also met a few friends from Japan. We talked online about font packaging. It is a unique experience to meet people in offline events. Taiwan friends stayed in the same hotel as me. So we get more chance to talk.

The most exciting part is to find QR code hidden in the square. Each gives you a link to a question. And you need 8/10 point to get a Gecko.

Catch a Geeko

Get to know many people. Drink non-alcohol beer. Exchange coins and bank notes.

Some cool guy's phone running Sailfish OS
Christian and me work on Wiki together for a long time
Chairman is also a fan of zoo

I enjoy it so much!

Code Journey #10

KDE:

  • Fixed JuK folder dialog always open on start
  • Translate tech base
  • POTD doesn't change daily
  • Bluetooth headset not detected when auto connect. Identify it as Linux kernel bug. Report to upstream

openSUSE:

  • Update Wiki FAQ page, still in progress
  • Chameleon theme: new navbar and footer design
  • Chameleon theme: dark mode
  • Apply theme to doc.opensuse.org
  • Update wiki theme