The 3DS has two screens, and when I am stuck in a dungeon room neither of them has the answer. So the console goes down, the phone comes out, I find the guide, lose my place in it, and by the time I pick the 3DS up again the mood has gone.
I wanted the guide on the console instead. So I built 3DS In-Game Guides, a Luma3DS plugin that shows the walkthrough of the game you are playing, right on the top screen.
What it does
Hold L + R + Select during a game. The game pauses and the guide appears on the top screen. Press B and the game carries on exactly where it was.
- Up/Down scrolls one line, and holding the button keeps scrolling.
- L/R jumps one page.
- B closes the guide and resumes the game.
- Plain Select stays with the game, so nothing changes in games that use it.
- It remembers. The page you were on is saved per game and survives restarts.
The bottom screen shows the file name, which line you are on and the game's title ID.
It is part of the Guide Watch family, so if you have read the others it will feel familiar: Switch, Miyoo and DS.
Install
You need a 3DS, 2DS or New 3DS running custom firmware (Luma3DS). I am not going to write a CFW guide here, the standard one at 3ds.hacks.guide is the place to start.
- Download 3DS-InGame-Guides.zip and copy its
lumafolder to the root of your SD card. You end up withSD:/luma/plugins/default.3gx. - Open guides.retromodlab.com/app in your browser, switch to 3DS mode and pick the card. It finds your installed games and writes one text file per game to
SD:/guides/3ds/. Cartridge games can be added by name. - On the console, open the Rosalina menu (L + Down + Select), turn on Plugin loader, and start a game.
The README says Luma3DS 10.3 or newer. I built and tested it on Luma 13.3.3 and 13.4, so that is what I can vouch for.
Where the guides come from
The walkthroughs are plain-text FAQs from the GameFAQs archive on archive.org. Many were written by fans years ago and are still the best guides for those games.
I don't host any of them, and neither does the plugin's repository. The browser tool fetches the text from archive.org and converts it on your machine into 64-column plain text, which is what fits the top screen. Game names come from hax0kartik's 3dsdb, and the index covers 214 games.
Each guide is saved as SD:/guides/3ds/<title id>.txt, where the title ID is the last 8 hex digits of the game's title ID. For A Link Between Worlds (EUR) that is 000EC400.txt. If a game has no guide, the plugin says so and shows the file name it looked for.
The hard problem
The plugin worked quickly. Then I found that the console reset every time I quit a game, which is not something you can ship.
Luma writes a crash dump when something goes wrong, so I parsed those, then rebuilt the plugin from the same commit and matched the addresses back to function names. The culprit was a double free. The plugin template calls delete menu after the menu finishes running, and in libctrpf 0.8.0 that object has already been freed. The fix was to simply not delete it. One line removed, after a lot of staring at hex.
Two smaller traps are worth knowing if you ever build your own plugin:
- The old Nanquitas template does not work on Luma 13, which rejects its plugin format. I built with the PabloMK7 libctrpf 0.8.0 Docker image instead.
- Asking for 2 MiB of plugin memory gives a fatal plugin error at boot. 5 MiB is the smallest block this version starts with, so that is what the plugin takes.
Known limits
I would rather you know these up front:
- It needs custom firmware. No Luma3DS, no plugin.
- Homebrew ports are not supported. Things like the zelda3 or Minish Cap ports cannot run CTRPF plugins, so the plugin does not load into them.
- Bravely Default (DX) crashes at the Nintendo logo with the plugin loader on.
- Ocarina of Time 3D shows an error at boot with the plugin loader on. I have not yet confirmed whether the loader alone causes it, so treat it as unresolved.
- A few memory-hungry games will not boot with any plugin loaded on an old 3DS. Mario & Luigi: Bowser's Inside Story + Bowser Jr.'s Journey is one. Turn the plugin loader off for those.
I tested on a 2DS and a 3DS XL. Anything beyond that is the README's word, not mine.
Credits
PabloMK7 for the maintained plugin template and libctrpf, Nanquitas for the original CTRPluginFramework, the Luma3DS team for the plugin loader, hax0kartik for 3dsdb, and the GameFAQs authors whose walkthroughs this reads, along with archive.org for keeping them around.
3DS In-Game Guides is free and open source on GitHub. If it saves you a trip to your phone mid-dungeon, you can buy me a coffee.