INTERSTELLAR DYNASTIES PROTOCOL
===============================

This document fails to describe the protocol used for client-server
communication in Interstellar Dynasties.

Introduction
------------

The protocol is a WebSocket protocol using text frames.

The server is at `ws://software.hixie.ch:13534/`.

Each frame has a series of parts, each terminated by a null (U+0000).

Strings are represented inline ("foo"). Integers and doubles are
represented as base-10 strings (e.g. "2.2"). Booleans are represented by
either the single character "T" or the single character "F".

The protocol is not self-describing; there is no way to distinguish a
number from a string or a string from a boolean. The client must know
what kind of message it is expecting to interpret it.

### Client to server

The first part of a message from the client to the server is an
integer conversation ID. When you start a new conversation, use a new
ID that's never been used before. Increasing the conversation count by
one each time is the normal convention.

Conversations are RPC calls in the form of methods called on objects.

The second part of each frame is the ID of the target object (also an
integer). The third part is the method (a string). Arguments are
passed as the remaining parts of the message.

For example, conversation 12 might start by invoking method `foo` on
object `34`, passing it a string argument "bar", a boolean true, and a
double 3.14:

```
12\034\0foo\0bar\0T\03.14\0
```

### Server to client

There are several kinds of messages received from the server. They
start with a string representing the kind of message. The remainder of
the message is null-terminated values as above.

#### `error`

This message has one argument. It is a conversation ID. This message
represents that the server failed to understand the last message sent
on that conversation, and the conversation (but not the connection) is
terminated.

#### `reply`

This message has at least two arguments.

The first is the conversation ID. The message represents a reply to
the oldest message sent by the client using this conversation ID that
has not yet received a reply.

The second argument is a boolean. The value true indicates success,
the value false indicates failure.

#### `change`

This message represents information from the server relating to one of
the objects to which the client has subscribed for change
notifications.

Arguments: the actor's ID, followed by the state of the actor.

#### `death`

This message represents a notification from the server regarding one
of the objects to which the client has subscribed for change
notifications, namely, that that object no longer exists.

Arguments: the actor's ID.

#### `news`

This message represents a notification for the player.

Arguments: the identity of the actor.

#### `dynasty`

This message represents information regarding the player's dynasty.

This consists of a description of the technologies available to the
player, in the form of an integer giving the number of technologies,
then, for each technology: the name of the technology, the value of
the technology's `Image` property (see below), and the kind of
environment that the technology can be built upon (see e.g. the
environment of each cell in a `grid` below).

Object 0
--------

The user's dynasty is represented by the object with ID zero.

Initially it has two methods, `login` and `create`. Once one of those
is successfully invoked, the other methods become available.

### `create`

This has two arguments, the username and password.

If the given username is new, a new dynasty (player) is created and
then the user is logged in (as if `login` was used).

If the user has already logged in or if the username is already in
use, then the conversation will get a "false" reply with no arguments.

### `login`

This has two arguments, the username and password.

If the user has already logged in or if the username and password did
not match, then the conversation will get a "false" reply with no
arguments.

If the username and password match, and if the user has not already
logged in, then a "true" reply is sent, with the following arguments:
game ID, dynasty name, the identity of the player's "home" actor (see
the actors section below for details on identity), and a description
of unlocked technologies (in the format described for `dynasty`
above). Then, the connection is subscribed to this "home" actor and
its parent actor, and `change` events are immediately sent for both.

### `change-password`

One argument: the new password. Always returns true.

### `build`

Arguments: the technology name being built, the ID of the actor on
which the technology is being built, and the location of where to
build the technology. The format of the location for the various
renderers is described below. If no format is available, it is not
possible to build on that actor.

The environment of the location where the actor is to be built must
match the environment of the technology to be built there. (Not
currently checked by the server.)

If successful, returns a "true" reply followed by the new object's
identity; the connection is then subscribed to that actor and a
`change` event is sent for this actor.

Otherwise, returns a "false" reply.


Actors
------

Objects other than the dynasty itself have different methods based on
what kind of actor they are.

### `get` method

All actors support this method. It has no arguments. If successful,
returns a "true" reply followed by the object's state; the connection
is then subscribed to that actor.

Otherwise, returns a "false" reply.

### Identity

Sometimes, actors report their identity as part of another message.
This consists of a string giving the type of renderer the actor
desires, and an ID which can be used to invoke methods on that actor.

### State

Sometimes, actors report their state as part of another message. An
actor's state depends on their renderer class.

In all cases, it starts with a count of properties, followed by the
properties themselves, each of which has a name, a type, and a value,
given in that order like all other arguments. Names are strings, types
are strings, and values match the described type. The possible types
and how their values are described are:

* "string": a string.
* "integer": an integer.
* "float": a double.
* "boolean": a boolean.
* "array": the value itself consists of multiple arguments, first giving a type (which currently itself can only be "string"), then the number of values, and then the values themselves.
* "actor": two arguments giving the actor's identity (renderer type and ID, as described above).
* "actor-nil": the value is not provided. This indicates that the property could normally have the value of an actor, but currently is empty.
* "dynasty": the value is the string name of a dynasty.
* "dynasty-nil": the value is not provided. This indicates that the property could normally have the value of a dynasty, but currently is empty.

Some of the properties imply the existence of methods, see below.

After the properties, the data depends on the kind of renderer. See
below.

### Properties

#### `Name`

Everything has a name. This is a string.

#### `Radius`

The size of the actor, approximated to a sphere, given as the radius
of that sphere in meters. An actor with a `Radius` also has a `Mass`.

Every actor that represents a physical thing in the universe has a
radius.

#### `Mass`

The mass of the actor, in kilograms. An actor with a `Mass` also has a
`Radius`. All physical things have a mass.

#### `ParentActor`

The identity of the actor that contains this one.

#### `Image`

A URL, which can be resolved using
`http://software.hixie.ch/fun/isd/images/client/` as the base URL, to
obtain the URL of a PNG that can be used as an icon for the actor.

All actors that have a parent have an image.

#### `ResearchTopics`

The value of this property is a list of strings representing topics
that can be researched by this dynasty.

This is always present if `SelectedResearchTopic` is present.

#### `SelectedResearchTopic`

The topic that this research facility is focused on.

This property implies the availability of the `set-research-topic`
method, which takes one argument, a string representing the new
research topic to select. (Must be one of the strings in
`ResearchTopics`.) The reply will be true if successful, false
otherwise (e.g. topic is invalid). No arguments in the reply.

#### `Prayers`

This property's value is an integer representing the number of prayers
received so far.

This property implies the availability of the `pray` method. This
method takes one argument: a message to send to the administrators. It
increases the `Prayers` count and always returns true.

#### `ThrusterMode`

The value is a string saying what the thrusters are doing: "tmOff"
means no, "tmFiring" means yes.

This property implies the availability of the `thruster-control`
method, which takes one argument: a string that is either "tmOff" or
"tmFiring". Setting this to "tmFiring" triggers a launch if the ship
is not in space already.

#### `CurrentOwnerDynasty`

For actors that can belong to a dynasty, the name of its current
dynasty.

#### `Contents`

An actor that represents the contents of this actor.

#### `NewsKind`

The type of news, from the list below.

* `Memo`: indicates a memoradum from the player's staff to the player.

Always combined with `NewsBody`. These properties apply to the `news`
renderer type.

#### `NewsBody`

A string representing the body of the news.

Always combined with `NewsKind`. These properties apply to the `news`
renderer type.


### Renderers

#### `space`

Space renderers represent solar systems and other gravitational
environments.

After the properties, they list a number of participants (children).

Then, for each child, in no particular order, the following is listed:

1. The x position of the child.
2. The y position of the child.
3. The x component of the velocity of the child.
4. The y component of the velocity of the child.
5. The identity of the child (this is multiple values; see above).

Locations are not supported for this renderer type. Trying to build on
an actor with this renderer will crash the server currently.

#### `grid`

Grid managers represent surfaces, e.g. of planets or ships.

After the properties, they list two integers, width and height
respectively. Then, for each row of the grid from the top, each cell
of the row is described, from left to right. For each cell, first the
cell's environment is given (used to determine if a technology can be
built there, see `dynasty` above), then a boolean indicating if the
cell is occupied, and if it is, the identity of the actor at that
cell.

Locations for grids consist of two arguments, integers, giving the X
and Y coordinate. Top left is 0,0.

#### `child`

These are leaf nodes in the tree. They have no children, and report
nothing after the properties. They might have a `Contents` property
though, which itself is an actor with contents.

Actors with this type do not support being the target of `build`.

#### `news`

These are messages to the player.

These have the `NewsKind` and `NewsBody` properties.

Actors with this type do not support being the target of `build`.
