Protocol
From Skycastle
The content may need to be clarified, split into sub-pages, or updated to reflect current status.
Be aware that there may be inaccuracies, contradictions, and outdated information on this page.
See also other pages needing cleanup.
| Completed Feature |
|---|
| This feature has been implemented, tested, and documented. It should work. |
| Other Completed Features |
Contents |
[edit] First level
On the lowest level, the communication between the server and the client happens with byte arrays / streams.
The Darkstar framework provides this and lower levels for us.
[edit] Second level
- The client can send action requests (=messages) to the server.
- The server can send messages to the client
The messages specify the sender and the target, the message type, and parameters. The parameters can be constructed from primitive types, simple collections, and game object ID:s.
Java serialization will probably not be used, instead maybe one of the (binary) protocols for the Atlas library will be used. Java serialization requires matching versions for the client and server, has various security risks, would not allow interoperation with clients / servers / tools in other languages, and might be somewhat verbose.
On the other hand, a simple protocol using primitive types and collections can also be restrictive in what it can easily express, and requires somewhat more implementation work, as well as custom serialization / communication code in more places.
TODO: How to handle the security, that is, which game objects are allowed to send what types of messages to other game objects, and how do we verify that messages that arrive over the network are from the game objects claimed?
[edit] Third Level
On this level we define some standard messages that GameObjects can handle, for example methods for discovering what actions, properties, sensors / ports, and such are available.
[edit] Fourth Level
This is where the game logic resides. On this level we can e.g. discover what actions are available to the player, and allow the user to bind different actions to different buttons in the UI. Here we are also interpretting e.g. position update messages, or chat room messages, and so on.
This level should ideally be handled in a modular way, where different modules can handle different kinds of messages for each game object (e.g. a physics module handles position updates and collisions, a health module handles healing ticks and damage messages, and creates life termination messages handled by the lifeAndDeath module, etc).
TODO: Update the stuff below, based on what we decide to use
[edit] Atlas
The basic data transfer and handshake will use the Atlas protocol developed by WorldForge. For the higher semantic level, we use our own messages, created from low level data types offered by Atlas.
The advantages of Atlas are:
- Already tried and tested
- The lower levels are game independent
- Allows protocol negotiation, and future extension
- Simple to implement, possible to implement only partially (some codecs).
Disadvantages are:
- The higher level object model is not well documented, and might be somewhat WF centric - but we will use our own anyway.
- There was a Java implementation at some point, not sure if it is up to date though. It appears a bit cryptic. We might need to roll our own (should not be too hard, if we only implement one codec).
[edit] Handshake and Codec Negotiation
Shakes hands and negotiates a codec that both the client and server knows.
See Atlas Handshake.
[edit] Data transfer layer
Transfer of structured data over the connection, using one of the available codecs.
The data can be:
- integers
- floats
- strings
- lists
- maps
See Atlas Codecs.
[edit] Content Layer
[edit] Terms and Definitions
- Actor
- Something that can do Actions, and can have Sensors, and can have control over other Actors.
- Controller
- Something that is controlling an Actor - can be a player client, a server side AI, or another Actor. The Controller can invoke actions and receive Sensations from the Actor.
- Action
- Something that an Actor can do. Allows controllers of an Actor that has the action to invoke it. Takes some number of parameters with some values (can be structured values, like lists).
- ActionRequest
- A request to execute a particular action, with some specified parameters. Sent by a Controller to an Actor it has control over.
- Sensor
- Part of an Actor. Allows Controllers of an Actor to receive some kind of Sensations.
- Sensation
- Produced by a Sensor, and sent to a Controller. Has a type, and some number of parameters.
- SensorType
- Some type of sensor. All sensations from a specific SensorType have the same possible SensationParameters. E.g. ChatSensorType, VisibleEntitiesSensorType, AttributeListSensorType, etc.
[edit] Overview
An Actor can be controlled by a Controller - either a client, or an on-server AI. In the case of on-server AI, the messages need not be encoded in the Protocol, but they are essentially similar.
The Controller sends ActionRequests to the Actor, and the Actor sends Sensations to the Controller.
The Controller can query the Actor for what Actions and Sensors it offers, and what other Actors it controls. The Controller can also subscribe and unsubscribe to Sensors to determine wether it will recieve Sensations from them.
Only a controlled Actor can be sent ActionRequests or sensor subscriptions. Other characters are only perceived as part of Sensations from a controlled Actor, and affected through Actions invoked on a controlled Actor. However, the controlled Actor may get control of other Actors in the game through some Action (e.g. driving a car, using a control panel, mind-controlling a goblin), and those controlled Actors can also be controlled by the controller of the Actor controlling them.
[edit] Login Sequence
The client has a local Actor called ClientActor, that provides client side actions and sensors, such as connectToServer, availableServers, etc. This way the client UI needs only to work with Actors, Actions, and Sensors, greatly simplifying it and allowing ease of extension.
As the player requests the connectToServer action through the ClientActor, the client connects to a server, and the ClientActor is assigned control over a ServerActor specific to that connection and server. The ServerActor resides on the server side, and is accessed from the client through a proxy. The ServerActor offers Actions such as loginToAccount, createAccount, as well as Sensors such as serverStats, serverDescription, systemMessages, ping, etc.
After a successful login action, the ServerActor gains access to an AccountActor, that has Actions such as createCharacter and controlCharacter, and Sensors like ownedCharacters.
After creating a new character, or taking control of an existing character, the AccountActor receives control of a CharacterActor. This is the basic avatar of the player in the game world, in a typical fantasy MMORPG this will be the human, elf, orc, etc. that the player controls in the game.
The CharacterActor can have actions such as 'use' or 'wield', that allows the CharacterActor to recieve control of other Actors, e.g. a car that offers driving actions, or a magic staff that has a fireball action, or a set of binoculars that have a sight Sensor with extended range, or a guild that has actions for managing members, and sensors such as guild chat channels.
[edit] Sending Actions
client: actionRequest
- String actorId - either the ID of the Actor, or a dot separated list of Actor ID:s, denoting a path from a directly controlled Actor to some Actor it controls.
- String actionId - an id for an Action provided by the specified Actor
- Map parameters - a map from parameter names to parameter values. The values can be any structured data. Unknown parameters are ignored by the server (allows extension mechanism).
ActionRequests do not have any response mandated by the protocol, but the Actor can provide a Sensor that sends the progress of some of the ongoing actions, and their success / failure.
[edit] Receiving Sensations from Sensors
The client can separately subscribe and unsubscribe from Sensors. This allows clients to conserve bandwidth, and makes it easier to implement e.g. simple mobile clients for handheld devices.
client: subscribeToSensor - the client subscribes to messages from some Sensor. The Sensor may send an update of the current state initially, e.g. of all visible entities, or about all character skill levels, or the last few messages in a chat channel, before it starts to just send changes for them.
- String actorId - either the ID of the Actor, or a dot separated list of Actor ID:s, denoting a path from a directly controlled Actor to some Actor it controls.
- String sensorId - an id denoting a specific Sensor that the client should receive Sensations from from now on.
client: unsubscribeFromSensor - the client wishes to stop recieving messages from a specified Sensor.
- String actorId - either the ID of the Actor, or a dot separated list of Actor ID:s, denoting a path from a directly controlled Actor to some Actor it controls.
- String sensorId - an id denoting a specific Sensor that the client should stop receiving Sensations from from now on.
server: sensation
- String actorId - either the ID of the Actor, or a dot separated list of Actor ID:s, denoting a path from a directly controlled Actor to some Actor it controls. This is the avatar that originated the Sensation.
- String sensorName - an id denoting a specific Sensor that the Sensation originated from.
- String sensorType - an id for the type of perception. E.g. chat messages, visible entity updates, and so on are all different SensorTypes.
- Map parameters - a map from perception parameters to parameter values. The parameters can be any structured data. Unknown parameters are ignored by the client (allows extension mechanism).
[edit] Querying available Actions, Sensors, and controlled Actors
This is done by requiring each Actor to have three standard Sensors, one for available Actions, one for available Sensors, and one for available controlled Actors.
The client could be subscribed to them by default by the server.

