Crafting a bluetooth Minecraft Watch with MetaWatch

A little bit of Friday silliness for you, wherein I manage to combine two recent pastimes, hacking the MetaWatch and playing Minecraft, by pulling a piece of game UI out into the real world.

Lately I’ve been experimenting with the possibilities of Bluetooth watches. While I was fooling with Travis Goodspeed’s PyMetaWatch library for talking to the MetaWatch from Python code on your PC, I remembered a fun hack that my friend Michael Dales had done to control lights in the real world from actions and switches in the virtual world of Minecraft.

Minecraft is an engrossingly open-ended game that involves exploring caves for minerals, then using those materials to build more tools and buildings. To complicate matters, there’s a day/night cycle, and night time brings zombies, skeletal archers, and other nasty ssssurprises. The upshot is that it’s a lot safer to travel during the day.

If you’re mining deep in a cave, though, how do you know when it’s safe to emerge from your spelunking to haul your loot home? Notch, the game’s creator, eventually added the ability to craft an astronomical clock in the game to tell you what time of day it was.

So, how did I get it on my wrist? Here’s the crafting recipe for this hack: I wrote a little mod for the Minecraft server that spit out the virtual world’s time of day, using V10lator’s lib24time library and the gratifyingly straightforward Bukkit Minecraft modding system. From there, I have a Python script that uses PIL and the assets from the game to render an approximation of the Minecraft watch at the given time of day.

Finally, I’m using my fork of PyMetaWatch to send the image from my Mac to the watch via bluetooth.

It works, but it’s very laggy right now. (Eagle-eyed Minecraft fans might have noticed that my screenshot above is more evocative than accurate.) The slowdown seems to be somewhere in the PyMetaWatch/lightblue combo, which is taking an agonizingly long time to send a bitmap to the watch. I can generally send a bitmap from my Android phone in less than a second, I suspect that either lightblue is configuring the bluetooth RFCOMM link for a ridiculously low speed, or there’s some overhead in the PyObjC bridge that it relies on. Let me know if you have any ideas.

Update (Sept. 17): Today I tried a different tack, involving an Android app loading the clock image from the Mac over wifi and sending it to the watch via MetaWatchManager, and it worked much better. Here are a couple more pictures showing the watch time more or less synced up with the time on the in-game clock:

  • uberfoo1337

    this is epic!!!!! keep it up! and then give it to android market! i’d buy it!

  • javispedro

    Pymetawatch is doing a 100ms sleep per each line sent, but a 25ms sleep is long enough in my fw version (search for “time.sleep” in the .py and try smaller values).

    Also, there’s a command to send two lines of the bitmap at once instead of one, but there seems to be a typo in the docs about this. I’ve posted in the forums…

    Theoretical max refresh speed would be 8x what you are getting now (4x increase due to reduced sleep time, and 2x increase due to two data lines instead of 1). However, I have no idea how to do better than that — which means uploading a 96×96 full screen bitmap is still in the seconds range:
    (96 lines / 2 lines per message ) x 0.025 seconds per message = 1.2 seconds.

    How fast is the Android program? I have no Android device to test.

  • Joe

    Thanks, Javier. I’ve already removed the 100ms delay from my fork of PyMetaWatch, but I’m seeing image push times on the order of a minute when running PyMetaWatch with lightblue on Mac OS X, hence my belief that there’s something stupid going on. (Things will get significantly better once I switch to 2-line packets, though.) On Android talking through OpenWatch/MWM, it only takes ~1sec, close to your theoretical speed limit. In previous experimentation, that’s just fast enough for interactive applications using the watch as a dumb terminal.

  • javispedro

    Something seems fishy with lighthouse then… if you completely remove the sleep() call, at least here under GNU/Linux the clock is bombarded with so many messages per second it ends up crashing/rebooting.

    Maybe Lighthouse’s doing buffering? I had that problem with Qt’s bluetooth wrappers.

  • Pingback: MetaWatch Hacks & Resources | The Incrementalist

  • V10lator

    Nice idea, never thought lib24time could be used for such a thing. :) To bad such a MetaWatch is priced at $199, else I would buy one just to try to recreate what you did.