Narya provides a framework for building realtime distributed systems with an emphasis on multiplayer online games (massive or otherwise). It is developed in Java and has an extensive set of features, such as:

  • presents: A distributed object and remote procedure call framework for creating realtime distributed systems.
  • crowd: A foundation for a multiplayer environment with notions of bodies and places, and support for chat and moving between places.
  • admin: Useful administrative functionality including a mechanism for declaring configuration that can be viewed and modified at runtime by an administrative client.
  • bureau: A framework for managing a network of code execution servers, which can be used to host ActionScript server-side code in addition to the Java server normally used by presents.


package com.threerings.bureau.client {


public class TestClient extends BureauClient

     * The main entry point for the bureau test client to be run in thane. Arguments:
     *   0: the token to use to log back into the server
     *   1: the bureau id of this instance
     *   2: the name of the server to log into
     *   3: the port to connect to on the server
    public static function main (argv :Array) :void
        if (argv.length != 4) {
            trace("Expected 4 arguments: (token) (bureauId) (server) (port)");

        var token :String = argv[0];
        var bureauId :String = argv[1];
        var server :String = argv[2];
        var port :int = parseInt(argv[3]);

        trace("Token: " + token);
        trace("BureauId: " + bureauId);
        trace("Server: " + server);
        trace("Port: " + port + " (parsed from " + argv[3] + ")");

        // create the client and log on
        var client :TestClient = new TestClient(token, bureauId);
        client.setServer(server, [port]);

    public function TestClient (token :String, bureauId :String)
        super(token, bureauId);

    protected override function createDirector () :BureauDirector
        return new TestDirector(_ctx);


import com.threerings.bureau.client.Agent;
import com.threerings.bureau.client.BureauDirector;
import com.threerings.bureau.Log;
import com.threerings.bureau.util.BureauContext;

class TestAgent extends Agent
    public override function start () :void
    {"Starting agent " + _agentObj.getOid());

    public override function stop () :void
    {"Stopping agent " + _agentObj.getOid());

class TestDirector extends BureauDirector
    public function TestDirector (ctx :BureauContext)

    // just use our test agent exclusively - in the real world, the agent created would depend 
    // on the object's type and/or properties
    protected override function createAgent (agentObj :AgentObject) :Agent
        return new TestAgent();
Multiplayer . URL.