A ComputerCraft emulator for Discord

May 11, 2021

Among the many ComputerCraft related things I maintain (seriously, I need to get better hobbies), is a chat bot for the ‘Minecraft Computer Mods’ Discord server. FAQBot-CC started as a small thing to script to answer questions (as the name might suggest), but now also supports searching the CC: Tweaked docs.

A couple of weeks ago, someone suggested a “Lua bot” - you write some code, the bot runs it, and prints out the output. A lot of servers have this already, it’s just the nature of ComputerCraft’s environment makes this a bit harder to get right - instead of capturing standard output, we need to display a terminal.

Incredibly, someone put together an implementation for this very quickly. I didn’t get a chance to test it, but it showed the principle was sound.

The CraftOS-PC bot in action, running some code.

This last weekend, I knocked together my own implementation1 in Java, built using ComputerCraft’s own jar, rather than an existing emulator (see 1 again). eval.tweaked.cc, as the project is now known, effectively acts as any other emulator. However, it is interacted with over HTTP rather than using a GUI. The emulator receives HTTP POST requests with a block of code in the body, starts up a new computer and runs the code. Once the code has finished, we take a screenshot and send it back to the client.

Implementing this all as a HTTP server may seem a little odd a choice, and is definitely rather over-engineered. However, we need a long-running process to avoid JVM startup times (otherwise the bot ends up being very sluggish), and using HTTP is a natural way to communicate with such a process.

This does have some rather fun side effects though. It being a plain-old HTTP server means we can expose it to the world, and interact with it in all the normal ways, such as this fun bash snippet:

$ curl -d 'print("Just testing some code!")' https://eval.tweaked.cc | display

Given this service, the actual Discord bot’s job is pretty simple. We find code blocks within a message2, and send them off to be run. The returned screenshot is then uploaded to Discord and we reply to the original message.

The new bot in action. Same as the old bot.

  1. I do have a rather unhealthy case of Not Invented Here syndrome.↩︎

  2. Using regex of course! If people use %eval on an uploaded Lua file, or reply to another message with %eval, we’ll try to run those instead.↩︎