3DS Support

With the basic logic in place it was possible to extend the program to support the 3DS as well as the DS-Lite, this would enable support for more games beyond those on the Game Boy Advance and Nintendo DS.

Implementing configurations

Previously, Shaoooh had only supported video capture via a capture card using Video4Linux and control via the Raspberry Pi Pico controller wired to the DS-Lite. In order to support different setups, configurations were added which could control how the video capture and control were performed, keeping the same logic for performing shiny hunts.

The original config for the DS-Lite is called “Shaoooh ショオーッ” and a new config called “Bishaan ビシアーン” was added for 3DS support. A sample config “Ditto メタモン” was added to allow some testing when no console was available.

InputRedirection

Luma3DS supports receiving button presses over a UDP socket. Using the InputRedirection client it was possible to recreate this functionality within Shaoooh.

Rather than sending inputs over a serial port, packets were send over UDP instead. This used a background tokio task, with a channel used to send the sequence of button presses to perform. Additional buttons were defined to represent the controls that exist for the 3DS and not the original DS. This includes the circle pad and the touchscreen.

NTR

NTR-HR can be used to receive encoded frames of the 3DS screens over a UDP socket. A TCP socket is used to setup the streaming and send a heartbeat packet. In order to reimplement this functionality in Shaoooh, Chokistream was used as a reference.

Detection

The 3DS era games had moved to 3D models rather than sprites, and so matching on a model rather than a sprite would be more challenging. Matching a 3D model would require capturing a frame at exactly the same point in the animation. Instead, matching the shiny star at the start of an encounter was used.

Wireless and reliability

A recommendation in guides to set up wireless streaming of the 3DS screens is to use a dedicated WiFi hotspot. Nintendo WiFi modules can be awkward to connect depending on security settings, and using a Raspberry Pi as a hotspot only allowed using more modern WiFi authentication than was supported by the 3DS.

It was possible to disable security but that would have resulted in leaving an open WiFi network which isn’t ideal for security. Any forwarding from the open hotspot was disabled to resolve this.

However, once access to the internet was disabled, the 3DS would disconnect from the WiFi network which could result in the 3DS freezing when using InputRedirection and NTR.

Luckily, others had already worked out how to make this connection test pass without an internet connection (FakeMii). As Shaoooh already created a web server for controlling the current hunt it was possible to add the X-Organization header to the response and pass the connection test. This also needed changing the startup process a bit, to wait for a connection test first, and then wait before trying to connect to the InputRedirection and NTR sockets.

Crashing

Despite things mostly working, after a while it’s quite likely that the 3DS will crash. Solving this is still in process, but trying to prevent sending the heartbeat request while the game is soft resetting might help.


Last modified on 2025-09-14