Finding the Right Ring-Con API

(learn about this date format)

I really enjoy playing Ring Fit Adventure, but it has a significant problem: it’s cathedral-style proprietary software. To make matters worse, Nintendo goes out of their way to make it difficult to install mods on their systems, and Ring Fit Adventure remains the only Nintendo-approved game that uses the Ring-Con or Leg Strap (I don’t even know if there’s a non-Nintendo-approved one). This is unfortunate. There’s plenty of people who have ideas about how Ring Fit Adventure could be improved or ideas about how else the Ring-Con could be used. I’m one of these people, and I want to make a game that uses the Ring-Con.

The first problem I’ve run into is input. Somehow, I have to give Godot (my game engine of choice) access to

Luckily, there is software out there that’s capable of collecting some or all of that information from Joy-Cons. Unluckily, the different software options aren’t necessarily compatible. For example, does Linux’s Joy-Con driver use the same axis numbers as this one? What about if you’re using joycond? Even if I do find a combination of drivers that is consistent across platforms, will those drivers support the Ring-Con?

What I need is an API that will provide the data in a way that is consistent across multiple platforms.

Ideal UX

Ideally, here’s what the user should experience when they first start the game. It’s largely the same as what happens when users start Ring Fit Adventure.

  1. If the left Joy-Con isn’t connected, have the user connect it through their OS.
  2. (Optional) Once the left Joy-Con is connected, have it give some sort of feedback to the user (something like setting the LEDs or vibrating).
  3. Once the left Joy-Con is connected, have the user put it in the leg strap and stand up
  4. If the right Joy-Con isn’t connected, have the user connect it through their OS.
  5. (Optional) Once the right Joy-Con is connected, have it give some sort of feedback to the user (something like setting the LEDs or vibrating).
  6. If the Ring-Con isn’t connected, have the user connect it.
  7. (Optional) Once the Ring-Con is connected, have the right Joy-Con give some sort of feedback to the user (something like setting the LEDs or vibrating).

In order to find the ideal API, I’m going to try to create a command-line program that walks the user through those steps. This will help me figure out what certain APIs are capable of and what they’re missing.

The candidates

joycon-python

This library isn’t a good option in this scenario, but I’m still glad that I took a look at it. Python is the programming language that I have the most experience with. Using a library written in Python gave me the opportunity to think through how I would implement the Ideal UX without worrying about learning a new language. Plus, it reminded me of something that I didn’t include in the Ideal UX: calibration. The experience in Ring Fit Adventure is so seamless that I didn’t even realize that calibration was necessary.

That being said, joycon-python isn’t a good fit for my situation. For one thing, Python is never (rarely?) fully compiled. Maybe I’m just superstitious, but I would rather choose something that’s less likely to add latency. More importantly, the library lacks Ring-Con support and crashes unpredictably (at least, it does on my system).

KaiseiYokoyama’s joycon-rs

At first glace, joycon-rs looked very promising. It’s well documented, provides some helpful examples, and targets Linux, macOS and Windows. Unlike the previous example, it’s written in Rust. I’m not very familiar with Rust, but it seems like a good language for this task.

joycon-rs lacks Ring-Con support, but I would be more than willing to at least try adding Ring-Con support. The real problem is that joycon-rs doesn’t work properly on my system. I’m experiencing this issue. There is a workaround, but I haven’t gotten it to work yet. Plus, it would nice if I didn’t have to tell users to install custom udev rules. That might be unavoidable, though.

Yamakaky’s joy

The first thing I noticed about joy was that its documentation is sparce. It is, however, the only software that I’m aware of that runs on Linux and can read the Ring-Con’s flex sensor.

joy includes joytk a command-line application that can retrieve data from the Ring-Con. To implement the Ideal UX, I ended up copying a lot of code from that tool. Having it as an example was very helpful.

joy, like the other candidates, has it’s fair share of problems. The difference with joy is that the problems that I feel confident that I can fix the problems it has. Adding documentation is going to be easier than fixing random crashes, compensating for gyro drift is going to be easier that adding Ring-Con support, and turning the code that I copied into public functions is going to be easier that debugging Linux-specific Bluetooth problems.

Others?

There’s plenty of other software out there that provide some sort of Joy-Con support. It’s very possible that I missed the best one. One in particular that I skipped over was the Windows-only Ringcon-Driver. Being multi-platform is a must for me, and I know very little about doing things the Microsoft way (i.e., using .sln files, Windows APIs, etc.). Making Linux-only software work on Windows is going to be much easier for me than making Windows-only software work on Linux.

Conclusion

The right API for my project is… something that doesn’t exist yet. joy, however, appears to be a good starting point. Here’s the current plan:

  1. Submit issues and pull requests to joy.
  2. Investigate options for including Rust code in Godot games.
  3. Create some sort of Godot asset that provides an API for interacting with Joy-Cons and Ring-Cons.
  4. Create an example project that implements the Ideal UX in Godot.
  5. Start creating a game!