Using Twig as an RPC Server

Twig can be used in two modes.  It can used directly as an XNA library, or it can be built as a server application that supports a simple text-based TCP protocol.

Overview

All objects on screen in Twig have a name string associated with them that can be used to identify them in commands.  The RPC server allows you to call object methods by transmitting "objectname: methodname args ..." over a TCP connection.  In principle, any method can be called.  However, there is the practical limitation that the server needs to understand how to parse its arguments from the text string.  The current system understands how to parse numbers, vectors, object names, strings, Booleans, and null.

Getting started

The Twig distribution includes an example project, ServerTest, that provides basic server functionality and that can be used as an example for building new server projects (see building a new server project).  It also includes an example client, TestClient, that you can use to manually send commands to the server.

To try the example applications:

TCP Protocol

The Twig server simply listens on a TCP port and talks a simple text-based protocol.  It's intended to be driven by planners or other systems running in separate processes and written in different languages such as Java.  If you write your client in one of the .NET languages, such as C#, it's probably best to link to Twig as a library and run it all in one process.

Connection

To connect to the server, simply connect to the appropriate TCP port on the machine running the server.  The default port as of this writing is 10001.

There is no handshaking protocol once the TCP port is opened, however, the server will respond with two lines, "TwigServer", and the version string for the Twig assembly (library) itself.  This will look something like "Twig, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null".

Command protocol

Commands are sent as single text lines of the form:

[ requestID ]  command

N.B: the brackets are not typed, they mean that the requestID is optional.  The optional requestID is an arbitrary decimal integer the server will use as a prefix to any status messages (such as Succeed or Fail) generated by this request.  The client is free to omit or reuse requestIDs.  The default requestID is -1, so all commands without an explicit requestID will have ID -1.

Status messages arrive asynchronously and take one of the following forms:

requestID: succeed
requestID: fail
requestID: fail ExceptionType: message
requestID: message text

where requestID specifies which request this message is attached to (-1 if no requestID was specified in the command).  Succeed means the command terminated normally.  Fail means the command failed and terminated.  If an exception was thrown, the second form of fail is used.  Message is a status message generated by the command.  It does not indicate that the command has terminated.

Specific Commands

Any command from the scripting language can be used.

Reporting data from the server

These commands are only available within the RPC server.  They are called as methods on the object named "server":

Command Description
server: report fieldOrPropertyName Prints the value of the specified property for every TwigObject
server: report fieldOrPropertyName includeStatic Same, but if includeStatic is false, objects tagged as static (e.g. trees) are omitted from the list.
server: report fieldOrPropertyName includeStatic interval Same, but continually prints the information at the specified interval (in seconds)

Reports are returned in the format:

requestID: message objectName=value ...

The requestID will be -1 if none was specified in the report command.  One objectName=value clause will be included for each object being listed.  If a repetition interval is specified, then multiple messages will be generated for this request and no succeed message will be generated (because the command will never terminate).  For example, you can obtain a steady report of the locations of objects using the command "17 server: report "Position" true 1.0", which would then generate a report similar to:

17 message pat=(5 0 0) table=(324)

each second.  Changing the 17 to another number will change the requestID at the beginning of the message, whereas changing the 1.0 to 0.5 will cause the system to generate reports twice a second rather than once a second.

Building a custom server project

You can build a new server project in one of three ways:

Changing the server's port number

The server's port number is specified in the constructor for the TwigServer object.  To change the port number, simply change the line:

Components.Add(new TwigServer(this));

in the InitializeTwigObjects() method of your server to:

Components.Add(new TwigServer(this, portnumber));

The default port number is specified by the constant TwigServer.DefaultPort, which as of this writing is 10001.

Adding models and other assets to the server

XNA includes a set of extensions to the Visual Studio build system to translate media assets such as models, texture maps, sounds, etc. into an optimize binary form that can be rapidly loaded at run time.  Each asset is stored in a .xnb file in the Content subdirectory of the application. 

Adding assets to the server project

The most straightforward way to add assets to the server is to add them to the project for the server inside Visual Studio.  To add a media asset to the server:

  1. Copy the file (e.g. a .x file for a 3D model) to the Content subdirectory of the source directory for the project (e.g. the Twig\ServerTest\Content directory if you are adding to the ServerTest project).
  2. In Visual Studio, go to the solution explorer, and right-click on the Content subproject of the server project.
  3. Select Add>Existing item
  4. Select the file and click OK.
  5. Run the project as normal.