Skyline - RetroBIOS¶
Technical notes
Nintendo Switch emulator for ARMv8 Android, written from scratch in C++ and Kotlin. Android package skyline.emu, versionCode 3, minSdk 29, with the debug variant taking a .dev suffix (build.gradle:23,28-29,120-121). ES-DE reaches it through its SKYLINE find rule and starts it with android.intent.action.VIEW on the content URI of the game. Development ceased and the README at the pinned commit records it; the code is split across skyline and skyline-dev, whose external file surface is identical (key_store.cpp :10-13 and shared_font_core.h:40-47 in both).
NCA, NRO, NSO, NSP and XCI are loaded (loader/). Two key files are read, from keys/ under the application internal files directory, which os.cpp:35 hands to the key store as its root. Both arrive through the in-app importer, which accepts only the two names and rewrites the trimmed pairs into that directory (KeyReader.kt:25-26,56-60); nothing else is consulted for keys, and there is no dev.keys or console.keys path.
No firmware is installed and none is read. The system version is answered from a hardcoded 9.0.0-4.0 structure (ISystemSettingsServer.cpp:9-10) and the system data archives a game asks for through OpenDataStorageByDataId are served as stub RomFS images from the application assets (IFileSystemProxy.cpp:84-90). Two are carried: 0100000000000806, the NgWord filter, holding 0.txt through 15.txt plus common.txt and version.dat, and 0100000000000823, NgWord2, holding ac_<0-15>b1_nx, ac<0-15>b2_nx and ac<0-15>_not_b_nx. A data id without a matching asset opens nothing.
The six shared fonts are the one place where a firmware file replaces a built-in one. Each is looked for in fonts/ under the application external files directory, which resolves to /storage/emulated/0/Android/data/skyline.emu/files/ (SkylineApplication.kt :19,41), and only when it is absent does the asset of the same name serve instead (shared_font_core.h:40-47). The emulator writes the shared font header itself, a magic followed by the length XORed with a key derived at shared_font_core.h:36-38, and then copies the whole file after it (shared_font_core.h:51-55), so the file it expects is the raw TTF payload rather than the headered form the firmware stores. Sizes are taken from the file and never checked, and the six together have to fit the 0x140A000 shared memory block.
A custom Vulkan driver can be loaded through adrenotools from gpu_drivers/
17 files | 1 required, 16 optional | 2 in repo, 15 missing
prod.keys required in repo
Production keys for content decryption
- Path:
keys/prod.keys - System: nintendo-switch
- Source:
app/src/main/cpp/skyline/os.cpp:35,app/src/main/cpp/skyline/crypto/key_store.cpp:12-13,app/src/main/cpp/skyline/crypto/key_store.h:30-39,app/src/main/cpp/skyline/crypto/key_store.cpp:46-62,app/src/main/cpp/skyline/vfs/nca.cpp:21-22,app/src/main/cpp/skyline/vfs/nca.cpp:126,app/src/main/java/emu/skyline/KeyReader.kt:83-88 - Platforms: emudeck
- Read as name=value pairs from keys/ under the application internal files directory. Supplies header_key, and the titlekek_XX, key_area_key_application_XX, key_area_key_ocean_XX and key_area_key_system_XX generation-indexed sets. An encrypted NCA without header_key fails with MissingHeaderKey, and one whose key area cannot be unwrapped fails with MissingKeyArea, so no retail title loads without this file. The importer accepts a pair only when the name contains an underscore and the value is hexadecimal.
title.keys optional in repo
Per-title keys
- Path:
keys/title.keys - System: nintendo-switch
- Source:
app/src/main/cpp/skyline/crypto/key_store.cpp:10-11,app/src/main/cpp/skyline/crypto/key_store.cpp:35-39,app/src/main/cpp/skyline/loader/nsp.cpp:14-21,app/src/main/cpp/skyline/vfs/nca.cpp:108-110,app/src/main/java/emu/skyline/KeyReader.kt:77-82 - Read as rights id to title key pairs from the same directory. A title key normally arrives instead from the .tik tickets carried inside an NSP, which are parsed and pushed into the same store, so this file is only needed when no ticket supplies one; that case fails with MissingTitleKey. The importer requires both halves of a pair to be 32 hexadecimal characters.
FontStandard.ttf optional missing built-in fallback
Shared font, standard
- Path:
fonts/FontStandard.ttf - System: nintendo-switch
- Source:
app/src/main/cpp/skyline/services/pl/shared_font_core.h:26,app/src/main/cpp/skyline/services/pl/shared_font_core.h:40-47,app/src/main/cpp/skyline/services/pl/shared_font_core.h:51-55 - Loaded from fonts/ under the application external files directory when present, otherwise from the asset of the same name, which carries Noto Sans CJK. Copied into the shared font block behind a header the emulator generates, so the expected content is the raw TTF payload.
FontChineseSimplified.ttf optional missing built-in fallback
Shared font, simplified Chinese
- Path:
fonts/FontChineseSimplified.ttf - System: nintendo-switch
- Source:
app/src/main/cpp/skyline/services/pl/shared_font_core.h:27,app/src/main/cpp/skyline/services/pl/shared_font_core.h:40-47,app/src/main/cpp/skyline/services/pl/shared_font_core.h:51-55 - Same lookup as the standard font, with a Noto Sans CJK asset behind it.
FontExtendedChineseSimplified.ttf optional missing built-in fallback
Shared font, extended simplified Chinese
- Path:
fonts/FontExtendedChineseSimplified.ttf - System: nintendo-switch
- Source:
app/src/main/cpp/skyline/services/pl/shared_font_core.h:28,app/src/main/cpp/skyline/services/pl/shared_font_core.h:40-47,app/src/main/cpp/skyline/services/pl/shared_font_core.h:51-55 - Same lookup as the standard font, with a Noto Sans CJK asset behind it.
FontChineseTraditional.ttf optional missing built-in fallback
Shared font, traditional Chinese
- Path:
fonts/FontChineseTraditional.ttf - System: nintendo-switch
- Source:
app/src/main/cpp/skyline/services/pl/shared_font_core.h:29,app/src/main/cpp/skyline/services/pl/shared_font_core.h:40-47,app/src/main/cpp/skyline/services/pl/shared_font_core.h:51-55 - Same lookup as the standard font, with a Noto Sans CJK asset behind it.
FontKorean.ttf optional missing built-in fallback
Shared font, Korean
- Path:
fonts/FontKorean.ttf - System: nintendo-switch
- Source:
app/src/main/cpp/skyline/services/pl/shared_font_core.h:30,app/src/main/cpp/skyline/services/pl/shared_font_core.h:40-47,app/src/main/cpp/skyline/services/pl/shared_font_core.h:51-55 - Same lookup as the standard font, with a Noto Sans CJK asset behind it.
FontNintendoExtended.ttf optional missing built-in fallback
Shared font, extended button glyphs
- Path:
fonts/FontNintendoExtended.ttf - System: nintendo-switch
- Source:
app/src/main/cpp/skyline/services/pl/shared_font_core.h:31,app/src/main/cpp/skyline/services/pl/shared_font_core.h:40-47,app/src/main/cpp/skyline/services/pl/shared_font_core.h:51-55 - Same lookup as the standard font, with a Roboto asset behind it.
0100000000000806 optional missing bundled
NgWord system data archive
- Path:
romfs/0100000000000806 - System: nintendo-switch
- Source:
app/src/main/cpp/skyline/services/fssrv/IFileSystemProxy.cpp:84-90 - Stub RomFS image served from the application assets when a game opens the data storage for this title id. Holds 0.txt through 15.txt, common.txt and version.dat.
0100000000000823 optional missing bundled
NgWord2 system data archive
- Path:
romfs/0100000000000823 - System: nintendo-switch
- Source:
app/src/main/cpp/skyline/services/fssrv/IFileSystemProxy.cpp:84-90 - Stub RomFS image served from the application assets when a game opens the data storage for this title id. Holds ac_<0-15>b1_nx, ac<0-15>b2_nx and ac<0-15>_not_b_nx.
binaryList.txt optional missing bundled
Time zone location list
- Path:
tzdata/binaryList.txt - System: nintendo-switch
- Source:
app/src/main/cpp/skyline/services/timesrv/core.cpp:272,app/src/main/cpp/skyline/services/timesrv/core.cpp:293,app/src/main/cpp/skyline/services/glue/ITimeZoneService.cpp:29,app/src/main/cpp/skyline/services/glue/ITimeZoneService.cpp:56 - Read from the application assets at time service init and used as the list of known locations. It names the 594 zone binaries under tzdata/zoneinfo/, each of which is opened by location name when a zone rule is loaded. The set is generated from tzdb 2021a in Horizon format.
version.txt optional missing bundled
Time zone data version
- Path:
tzdata/version.txt - System: nintendo-switch
- Source:
app/src/main/cpp/skyline/services/timesrv/core.cpp:289 - Read from the application assets at time service init and reported as the time zone binary version.
profile_picture.jpeg optional missing bundled
Default user profile image
- System: nintendo-switch
- Source:
app/src/main/cpp/skyline/services/account/IProfile.cpp:66 - Opened from the application assets when a game asks the account service for the profile image of the emulated user.
blit.vert.spv optional missing bundled
Blit vertex helper shader
- Path:
shaders/blit.vert.spv - System: nintendo-switch
- Source:
app/src/main/cpp/skyline/gpu/shaders/helper_shaders.cpp:201,app/src/main/cpp/skyline/gpu.cpp:403 - Opened from the application assets when the GPU helper shaders are built. Compiled at build time from app/src/main/shaders/blit.vert.
blit.frag.spv optional missing bundled
Blit fragment helper shader
- Path:
shaders/blit.frag.spv - System: nintendo-switch
- Source:
app/src/main/cpp/skyline/gpu/shaders/helper_shaders.cpp:201,app/src/main/cpp/skyline/gpu.cpp:403 - Opened from the application assets when the GPU helper shaders are built. Compiled at build time from app/src/main/shaders/blit.frag.
clear.vert.spv optional missing bundled
Clear vertex helper shader
- Path:
shaders/clear.vert.spv - System: nintendo-switch
- Source:
app/src/main/cpp/skyline/gpu/shaders/helper_shaders.cpp:328,app/src/main/cpp/skyline/gpu.cpp:403 - Opened from the application assets when the GPU helper shaders are built. Compiled at build time from app/src/main/shaders/clear.vert.
clear.frag.spv optional missing bundled
Clear fragment helper shader
- Path:
shaders/clear.frag.spv - System: nintendo-switch
- Source:
app/src/main/cpp/skyline/gpu/shaders/helper_shaders.cpp:328,app/src/main/cpp/skyline/gpu.cpp:403 - Opened from the application assets when the GPU helper shaders are built. Compiled at build time from app/src/main/shaders/clear.frag.
Generated on 2026-08-23T16:12:06Z