Boktai
An intro that is longer than the actual project
I’m a big fan of excentric mechanics in video-games. It seems everyone I talk to like them, often I am told how someone fondly remember the times they had to close their Nintendo DS in order to solve a particular zelda puzzle, look at the back of Metal Gear Solid’s box to find Meryl’s codec number or dip a letter in water in for a secret message. I’m not blind to the fact most of them are anti-piracy measurements, I just choose to appreciate the effort and creativity, specially when it comes to examples that don’t fall under that category at all.
Wario Ware Inc. is a collection of mini-games for the GBA, it’s sequel for the same console, titled “Twisted!”, would incorporate a gyroscope on it’s cartridge and have you sway and turn the whole console around causing extreme confusion for a young me when the game wouldn’t respond to being played on an emulator. I would go as far as slightly turning the monitor to see if by any chance it happened to work, I’ll let the reader figure it out if it did so.
This concept enamoured me and so I started paying attention to games that would go further to create an experience unique to it. One such game is Boktai, also a gameboy advance game with a UV light sensor in it’s cartridge, allowing the player to use the power of sunlight to get an advantage in gameplay, isn’t that neat?
Due to my emulation ways, I never got to experience the game, which I could, there are patches that makes is so they player can manually control the sunlight level in-game, but needless to say that to me it misses the point, but now I’m a adult, which means I can easily buy this old, out of fashion video-game for a couple of do-

Which means I can easily buy a microcontroller and a UV light sensor, set that on my window and emulate the game updating the values by scripting RAM memory manipulation. In all due seriousness I just thought it’d be a fun project. Some emulators, namely bizhawk and mGBA offer lua scripting, mGBA even offers neatly setup signals so you can run code on events, such as per frame, socket support and offers linux support, so I’m going with that one.
Manual patcha example:
The project rough first round
This is a description of my first idea, which was a very baseline idea of concepts I knew I could work with, the lowest denominator for basic software support on all ends.
UV sensor
It’s just the cheapest one I could get my hands on, a Guva S12SD, got myself a dark light flashlight just so I could test it at night time when I usually do programming and the hardest part was getting esp-idf autocomplete to behave on nvim, which I didn’t completely, but that’s neither here or there.
The program is as simple as a reading loop and writing the value to serial. With some data cleaning to make sure peaks and valleys while reading are less regular, reading multiple samples and removing outliers does the trick just fine.
Reading Serial
After confirming my readings were correct (thank you UV flashlight), it was time to take that information being passed over via serial to my computer, a python script to read serial was all I needed, to have the data available for the lua script on the emulator, I then wrote it to a file, rewriting it from time to time with new values.
Writing to RAM
With the data free for me to access and being updated regularly, it was now time to read it from a lua script running inside mGBA. inside that environment I have access to function that write values to addresses in the emulated GBA’s RAM, the big problem is finding out which address to write to, lucky for me, I stand on the shoulders of giants, and that patch that let’s you manually control the readings has in it the address to which I want to write to and also an array of corresponding values to the sunlight meter in-game. Horray!
It’s not over yet!
But it’s close, there is still need to calibrate our readings, my UV light sensor and the game’s original don’t work on the same range, so we’re in for the waiting game, I need a sunny day to see what UV readings would look like. Lucky for me, I had a sunny streak the following week from when I programmed this project. Placing the reader next to my window I then was able to get a good sunny reading, couple of hours later I decided what my midway sunny would look like and everything in between was a simple linear calculation.

The project cleanup.
Well, when first doing this I really was doing it just for me, and didn’t really bother to research a lot before started doing it, things like mGBA’s scripting tools handling tcp sockets, which is very neat! Not only it kills the need for a middle man file to transfer data(python script), the lua script is also notified of a new value, unlike the file reading which had to occur every frame or at least be timed since I didn’t know exactly when a value was updated.
But all this begs the question… if I’m able to host a TCP server, why not use it on my microcontroller and connect to the lua script server? Upside would be being able to skip a python script altogether, the downside is a bit more configuration on the microcontroller end.
In the end I decided to do… both.
Cleaned up microcontroller
I tried getting it as simple as I could, by commenting a line you decide weather you run the WiFi version or the serial version of the code, change the GPIO of choice and you’re done! By sending the raw gathered data to the server, we don’t even have to put our hands in the arduino again.
Cleaned up python server
If you’re using the serial version of the previous code, this script will bridge the serial connection with the TCP client for the server, it leaves data unchanged and just passes whatever messages is receives through the serial forward. I have also compiled 2 windows executables to facilitate the life of any Windows users, lord knows they have it hard enough already.
Cleaned up lua script
The script is divided into 2 parts. The UV server is an almost 1:1 copy of mGBA’s TCP server example, but we’re calling a function from another file, calibration.lua, which in turns holds a map that determines what signal levels should be translated to what in-game sun levels, while trying to calibrate all you’d need to do is changes values here and resetting the server on mGBA’s scripts.

Future work.
You can find all the source code and instructions on how to get this project running on my git, don’t forget to check out the project’s wiki page
There are 4 games in the series, 3 of them for the gba, which would be nice to add, mGBA scripting does have a way to know which game is loaded, so a simple query by the client asking which game should it be configured for should do the trick, if there is even need to do that, RAM position is likely to change between games.
The last game in the series is on the Nintendo DS, which I have not done any research into the emulators supporting scripting, and due to it’s more complicated setup, as in, the game’s sunlight reading comes from a gba cart being inserted on the gba slot of the original nintendo DS only, it might not be as straight forward as it has been for gba. But alas, I have no idea, I’ll cross that bridge when I get there.
