RobotQuest is a MMO, programming game. Instead of playing RobotQuest directly, you write a program that plays it for you. Your program communicates with the game server API over HTTP by sending and receiving JSON messages. Written in HTML, Haskell, with MongoDB
Haskell JavaScript CoffeeScript HTML CSS Shell
Latest commit 9832857 Aug 28, 2016 @Qinusty Qinusty committed with Robotquest domain removal (#2)
Domain redirects to a spam website
Failed to load latest commit information.
test changed to commands May 12, 2012
Api.hs removed cache on objects. it messes things up May 31, 2012


RobotQuest is a MMO, programming game. Instead of playing RobotQuest directly, you write a program that plays it for you. Your program communicates with the game server API over HTTP by sending and receiving JSON messages.

All players share a single world

The Viewer lets you watch the game being played live.

The Documentation will teach you how to connect to the game and control your minions.

The Source is here on github

Also see Status. I don't have plans to continue development. Fork and reuse at will.

What can I do?

You can create minions (heroes or monsters), move them, and attack things near you. There is an AI player that spawns minions of increasing degrees of danger to give you trouble.

What's the goal?

You can see who has the most kills and has survived the longest on the Viewer. Other than that it's up to the players. The game will change signifiantly depending on the programs written for it and as new features are added.


Please respect the following rules. The server will eventually enforce them.

  1. Spawn with purpose - The API allows you to spawn multiple minions per player. Explore getting minions to work together, but don't spawn one on every square or anything. Consider having internal rules, like you can only spawn a minion when you kill one.

  2. Single player per program- You can try many different approaches to the game, but idea is that you write a program, which is a player. If you want to try a different approach, feel free to turn your old program off and use the same player name, or use a different player name, but don't spam player accounts

Feature Ideas

  • Blocks - Place walls down on the map that block movement
  • Gold - Collect gold
  • Store - Spend gold to buy items (upgrades)
  • Trading - Swap gold or items with other minions
  • Big World - Infinite or much larger world. Safe zones?
  • Limit Player Creation - right now it's completely open
  • Limit Spawning - make it a resource of some kind

Technical Details

The application was written in Haskell (ghc 7.2+), with the Scotty Web Framework, mongodb, some HTML and of course, JSON.

When players issue a command, it saves those on their minion object. A game timer fires once a second, grabbing all the commands and resolving them in haskell before saving out all the changes at once.

I'll write more detailed articles soon on Specifically, I'd like to address the difficulties of developing a web app in haskell.

To run locally

  1. install haskell platform 2012
  2. cabal install cabal-dev
  3. cabal-dev install within the directory


I don't know if I'll continue work on this. See Feature Ideas for where I was planning on going next.

The server is not really production ready. Too many bots will make it drag down. It keeps breaking.

Please fork and do whatever you want with it.







All routes are relative to the root domain:

curl -X GET

All types sent and received from the server are in JSON. Don't forget to set "Content-Type: application/json" and Content-Length (good libraries will do this for you)

This includes the Id type, which is just a JSON string. Run everything through your JSON parser and all will be well

Supports CORS: Cross-Origin Resource Sharing. You should be able to hit the API from another domain even from a browser.


Here are three complete examples:

The following examples are in psuedocode

Control a minion

# register our player
player = {name:"example", source: ""} = POST "/players" player

# spawn a minion
minion = {x: 0, y: 5, name:"example1", sprite: "dragon-1-3"} = POST "/players/$" minion

# move our minion
POST "/minions/$$" {action: "Move", direction: "Right"} 

# remove our minion
DELETE "/minions/$$"

See what is going on

game = GET "/game/info"
repeatEvery game.tick 
  objects = GET "/game/objects"
  for minion in objects
    print minion



{ message: "Space occupied" }

Any method can return a Fault instead of its regular response.





Note that this will include quotes when it comes down. This is valid JSON. Just run it through your normal JSON decoder and it will come out a string


    width: 25,
    height: 20,
    tick: 1000

tick - Game tick in ms. How often you can send commands and poll for information

width, height - World dimensions in squares


    name: "sean",
    source: ""

name - A unique player name for your program. source - Bot homepage. Source code preferred.


// To Server
  name: "rat",
  sprite: "monster1-1-4",
  x: 10,
  y: 10

// From Server
  name: "rat",
  sprite: "monster1-1-4",
  x: 10
  y: 10,

  // generated fields
  state: "Active",
  kills: 0,
  created: "2012-05-03T12:06:48.666Z",
  player: "AI",
  id: "6dc21b03a79fa15d",

name - The name chosen for the minion by its player.

sprite - Player-chosen sprite

x, y - Position in squares

state - Active or Dead. If a minion dies, the server will send down Dead once, then the minion will no longer appear in the result of /game/objects

player - Name of the controlling Player


Careful, I'm case sensitive!

    action: "Move",
    direction: "Left"

action - "Move", "Attack"

direction - "Left", "Right", "Up", or "Down"


Each route lists the url, the body it expects (if any), and what it returns. All types are JSON

GET /game/info

Always call this when you start. Respect the tick and size

returns GameInfo

GET /game/objects

Call this every tick to know where things are in the game. If a minion dies, it will come back one last time with state: "Dead", after which it will stop appearing in this call.

returns [Minion]

POST /players

Register your player. Note that the id returned from this is secret. You use it to spawn and command your minions.

body Player
returns Id

GET /players/:name

Info about another player

returns Player

POST /players/:playerId/minions

Spawn a minion on the map

body Minion - only send {name, sprite, x, y}
returns Id

GET /minions/:minionId

All available details for a minion.

returns Minion

POST /players/:playerId/minions/:minionId/commands

Issue a command to one of your minions. The command will be executed at the next game tick. If you issue more than one command per tick it will replace your previous command.

body Command
returns Ok

DELETE /players/:playerId

Remove your player

returns Ok

DELETE /players/:playerId/minions/:minionId

Remove one of your minions

returns Ok


I am using the extraordinarily complete, free, angbandtk dungeon tileset. When creating a minion, you can choose the sprite that represents it. The format is:


where sheet is the name of one of the following sheets, and x and y are the 0-indexed offset from the top left. For example, the dark blue ghost is undead-0-0, while the phoenix is uniques-8-5