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.
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.
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.
-
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.
-
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
- 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
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 http://seanhess.github.com. Specifically, I'd like to address the difficulties of developing a web app in haskell.
To run locally
- install haskell platform 2012
cabal install cabal-dev
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.
- GET /game/info
- GET /game/objects
- POST /players
- GET /players/:name
- POST /players/:playerId/minions
- GET /minions/:minionId
- POST /players/:playerId/minions/:minionId/commands
- DELETE /players/:playerId
- DELETE /players/:playerId/minions/:minionId
All routes are relative to the root domain: http://robotquest.tk
curl -X GET http://robotquest.tk/game/info
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
# register our player
player = {name:"example", source: "http://github.com/seanhess/robotquest"}
player.id = POST "/players" player
# spawn a minion
minion = {x: 0, y: 5, name:"example1", sprite: "dragon-1-3"}
minion.id = POST "/players/$player.id/minions" minion
# move our minion
POST "/minions/$player.id/minions/$minion.id" {action: "Move", direction: "Right"}
# remove our minion
DELETE "/minions/$player.id/minions/$minion.id"
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.
"Ok"
"6dc21b03a79fa15d"
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: "http://github.com/seanhess/robotquest"
}
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
Always call this when you start. Respect the tick and sizereturns GameInfo
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]
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
Info about another player
returns Player
Spawn a minion on the map
body Minion - only send {name, sprite, x, y}
returns Id
All available details for a minion.
returns Minion
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
Remove your player
returns Ok
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:
sheet-x-y
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