Messaging Protocol ================== Communication with a kRPC server is performed via Protocol Buffer messages. The `kRPC download `_ comes with a protocol buffer message definitions file (:github-blob:`schema/krpc.proto `) that defines the structure of these messages. It also contains versions of this file for C#, C++, Java, Lua and Python, compiled using `Google's protocol buffers compiler `_. Invoking Remote Procedures -------------------------- Remote procedures are arranged into groups called *services*. These act as a single-level namespacing to keep things organized. Each service has a unique name used to identify it, and within a service :ref:`each procedure has a unique name `. Remote procedures are invoked by sending a request message to the RPC server, and waiting for a response message. The request message contains one or more procedure calls to run, which include the names of the procedures and the values of their arguments. The response message contains the value(s) returned by the procedure(s) and any errors that were encountered. Requests are processed in order of receipt. The next request from a client will not be processed until the previous one completes execution and it's response has been received by the client. When there are multiple client connections, requests are processed in round-robin order. Within a single request, the procedure calls are also processed in order of receipt. The results list in the response is also ordered so that the results match the calls. .. _communication-protocol-anatomy-of-a-request: Anatomy of a Request ^^^^^^^^^^^^^^^^^^^^ A request is sent to the server using a ``Request`` Protocol Buffer message with the following format: .. literalinclude:: /communication-protocols/krpc.proto :language: protobuf :start-at: message Request { :end-before: message Response { A request message contains one or more procedure calls. This allows efficient batching of multiple calls in a single message, if desired. The fields of a procedure call are: * ``service`` - The name of the service in which the remote procedure is defined. * ``procedure`` - The name of the remote procedure to invoke. * ``service_id`` - The integer identifier of the service in which the remote procedure is defined. * ``procedure_id`` - The integer identifier of the remote procedure to invoke. * ``arguments`` - A sequence of ``Argument`` messages containing the values of the procedure's arguments. The fields of an argument message are: * ``position`` - The zero-indexed position of the of the argument in the procedure's signature. * ``value`` - The value of the argument, encoded in Protocol Buffer format. Ignored when ``is_null`` is set. * ``is_null`` - Whether the argument's value is null. When set, the argument is null and ``value`` is unset. Only permitted for parameters that accept null. The service containing the procedure to call is specified by setting either ``service`` or ``service_id``. The procedure to call is specified by setting either ``procedure`` or ``procedure_id``. Use of ``service`` and ``procedure`` (i.e. descriptive strings) should be preferred as these will not change between server versions. For clients where code size or communication overhead must be kept to an absolute minimum, ``service_id`` and ``procedure_id`` can be used. However, note that the identifiers may change between server versions. The ``Argument`` messages have a position field to allow values for default arguments to be omitted. See :ref:`communication-protocol-protobuf-encoding` for details on how to encode the argument values. .. _communication-protocol-anatomy-of-a-response: Anatomy of a Response ^^^^^^^^^^^^^^^^^^^^^ A response is sent to the client using a ``Response`` Protocol Buffer message with the following format: .. literalinclude:: /communication-protocols/krpc.proto :language: protobuf :start-at: message Response { :end-before: // Messages for receiving stream updates A response message contains one or more results, corresponding to the procedure calls made in the associated request message. The ``value`` field of a procedure result message contains the value of the return value of the remote procedure, if any, encoded in protocol buffer format. See :ref:`communication-protocol-protobuf-encoding` for details on how to decode the return value. The ``is_null`` field indicates that the return value is null. When it is set, the ``value`` field is unset and must be ignored. This is only permitted for procedures whose return value is nullable. If an error occurs processing a request message, the ``error`` field in the response message will contain a description of the error. If an individual procedure call encounters an error, the ``error`` field in the corresponding procedure result message will contain a description of the error. The fields of an error message are: * ``service`` - If the error was caused by an exception, this is the name of the service in which the exception type is defined. * ``name`` - If the error was caused by an exception, this is the name of the exception type. * ``description`` - A human readable description of the error * ``stack_trace`` - If the error was caused by an exception, this is a server-side stack trace for the exception. Example RPC invocation ^^^^^^^^^^^^^^^^^^^^^^ The following Python code invokes the ``GetStatus`` procedure from the :ref:`KRPC service ` using an already established connection to the server (the ``rpc_conn`` variable). The ``krpc.schema.KRPC`` package contains the various Protocol Buffer message formats compiled to python code using the Protocol Buffer compiler. The ``send_message`` and ``recv_message`` are helper functions used to send/receive messages from the server. .. literalinclude:: /scripts/communication-protocols/tcpip/RPC.py :start-at: call = KRPC.ProcedureCall() .. _communication-protocol-protobuf-encoding: Protocol Buffer Encoding ^^^^^^^^^^^^^^^^^^^^^^^^ Values passed as arguments or received as return values are encoded using the Protocol Buffer version 3 serialization format: * Documentation for this encoding can be found here: https://developers.google.com/protocol-buffers/docs/encoding * Protocol Buffer libraries in many languages are available here: https://github.com/google/protobuf/releases The ``is_null`` field on the ``Argument`` or ``ProcedureResult`` message signals a null value of any type. When it is set, the ``value`` field is unset and carries no encoded value. Null is signaled this way because the encoding of every type assigns a meaning to all byte sequences, leaving no spare value for null. A zero-length ``value``, an empty collection for example, is a valid encoding and is distinct from null. .. _communication-protocol-streams: Streams ------- Streams allow the client to repeatedly execute an RPC on the server and receive its results, without needing to repeatedly call the RPC directly, avoiding the communication overhead that this would involve. A client can create a stream on the server by calling :ref:`communication-protocol-add-stream`, or stream the value of a server side function by calling :ref:`communication-protocol-add-function-stream`. An :ref:`event ` is also a stream. Each call creates a new stream with a new identifier, including a call for the same RPC or function as an existing stream. The stream sends its first result in the update after it is added. A stream over a game object that is not loaded sends no result until the object loads. A stream over a procedure that is not available in the current game scene sends no result until the game returns to a scene where it is. An event still sends its first result, which says whether it has fired. Once the client is finished with the stream, it can remove it from the server by calling :ref:`communication-protocol-remove-stream`. Streams are automatically removed when the client that created it disconnects from the server. Streams are local to each client and there is no way to share a stream between clients. The RPC for each stream is invoked every `fixed update `_ and the return values for all of these RPCs are collected together into a stream update message. This is then sent to the client over its stream server connection. If the value returned by a streams RPC does not change since the last update that was sent, its value is omitted from the update message in order to minimize network traffic. A client can also control the rate of the stream, by specifying a target number of Hertz with :ref:`communication-protocol-set-stream-rate`. The server computes a time delay from the target rate, and only updates the stream if at least that time has passed since the last time the stream was updated. The first result travels on the stream connection and the ``AddStream`` response on the RPC connection, so the result can arrive first. The same holds for every response carrying an ``Event`` message. A client keeps the results for an identifier higher than any it has been given, and applies them once the response carrying that identifier arrives. The server issues identifiers in increasing order, so a client notes each identifier in the order the responses arrive. A result for a lower identifier with no stream on the client is for a stream that has ended, and is dropped. Anatomy of a Stream Update ^^^^^^^^^^^^^^^^^^^^^^^^^^ Stream updates are sent to the client using a ``StreamUpdate`` Protocol Buffer message with the following format: .. literalinclude:: /communication-protocols/krpc.proto :language: protobuf :start-at: message StreamUpdate { :end-before: message StreamResult { This contains a list of ``StreamResult`` messages, one for each stream that exists on the server for that client, and whose return value changed since the last update was sent. It has the following format: .. literalinclude:: /communication-protocols/krpc.proto :language: protobuf :start-at: message StreamResult { :end-before: // Messages for receiving information about the server The fields are: * ``id`` - The identifier of the stream. This is the value returned by :ref:`communication-protocol-add-stream` or :ref:`communication-protocol-add-function-stream` when the stream is created, or the stream identifier in an ``Event`` message. * ``result`` - A ``ProcedureResult`` message containing the result of the streams RPC. This is identical to the ``ProcedureResult`` message returned when calling the RPC directly. See :ref:`communication-protocol-anatomy-of-a-response` for details on the format and contents of this message. A result with its ``error`` field set is the last result for that stream. The server removes the stream after sending it, and sends nothing more for its identifier. When the server removes a stream itself, for example an event that has finished, the error is a ``StreamRemovedException`` from the ``KRPC`` service. A stream removed by the client with :ref:`communication-protocol-remove-stream` gets no final result. .. _communication-protocol-events: Events ------ Events are a wrapper over a stream that returns a boolean value. The event is triggered when the stream returns true. An event is created by :ref:`communication-protocol-add-event` or by another remote procedure with an event return type. The procedure returns an ``Event`` message, which contains a ``Stream`` message describing the underlying stream for the event. The stream starts when the event is created, and its first result says whether it has fired. The format for an ``Event`` message is simply the following: .. literalinclude:: /communication-protocols/krpc.proto :language: protobuf :start-at: message Event { :end-before: message Status { .. _communication-protocol-krpc-service: KRPC Service ------------ The server provides a service called ``KRPC`` containing procedures that are used to retrieve information about the server and to manage streams. The service has other members, such as the ``GameScene``, ``Paused`` and ``Clients`` properties and the ``HoldTick`` procedure. They are called like the members of any other service, so the getter for ``GameScene`` is the procedure ``get_GameScene``. See :ref:`communication-protocol-procedure-names` for the naming rules, and the :ref:`communication-protocol-service-description-message` for the full list of members. GetStatus ^^^^^^^^^ The ``GetStatus`` procedure returns status information about the server. It returns a Protocol Buffer message with the format: .. literalinclude:: /communication-protocols/krpc.proto :language: protobuf :start-at: message Status { :end-before: // Multiplexed request messages The ``version`` field contains the version string of the server. The ``protocol_version`` field contains the protocol version of the connection, which is 0 for a client that sent none. The remaining fields contain performance information about the server. .. _communication-protocol-get-services: GetServices ^^^^^^^^^^^ The ``GetServices`` procedure returns a Protocol Buffer message containing information about all of the services and procedures provided by the server. The format of the message is: .. literalinclude:: /communication-protocols/krpc.proto :language: protobuf :start-at: message Services { :end-before: message Service { This contains a single field, which is a list of ``Service`` messages with information about each service provided by the server. The content of these ``Service`` messages are :ref:`documented below `. .. _communication-protocol-add-stream: AddStream ^^^^^^^^^ The ``AddStream`` procedure adds a new stream to the server. Its argument is the RPC to invoke, encoded as a ``ProcedureCall`` message. The procedure returns a ``Stream`` message describing the stream that was added. See :ref:`communication-protocol-anatomy-of-a-request` for the format and contents of this message. See :ref:`communication-protocol-streams` for more information on working with streams. .. _communication-protocol-add-function-stream: AddFunctionStream ^^^^^^^^^^^^^^^^^ The ``AddFunctionStream`` procedure adds a stream that evaluates a server side function on each update. Its argument is the function, built using the ``KRPC.Expression`` class. The procedure returns a ``Stream`` message describing the stream that was added. The stream's values have the type given by the function's ``ReturnType`` property. The function must take no parameters. Any exception from the function ends the stream with that error, including one for a game object that is not loaded. .. _communication-protocol-add-event: AddEvent ^^^^^^^^ The ``AddEvent`` procedure adds an event that fires when a server side function evaluates to true. Its argument is the function, built using the ``KRPC.Expression`` class. The function must take no parameters and return a ``bool``. The procedure returns an ``Event`` message describing the event's stream. See :ref:`communication-protocol-events` for the format of this message. The function is evaluated on each stream update, and the event fires on every update it returns true. A rate set with :ref:`communication-protocol-set-stream-rate` limits how often the function is evaluated. Any exception from the function ends the event's stream with that error, including one for a game object that is not loaded. .. _communication-protocol-run-function: RunFunction ^^^^^^^^^^^ The ``RunFunction`` procedure evaluates a server side function once, within a single physics tick, and returns the value it produces. Its first argument is the function, built using the ``KRPC.Expression`` class. The value is returned as a ``bytes`` result holding the value's ordinary encoding, at the function's return type. The second argument is a list of the function's arguments, one per parameter of a function built with ``Expression.Lambda``. Each holds the value's ordinary encoding at the type given by the function's ``ParameterTypes`` property, and is null for a null value. A function that is not a lambda takes no arguments, and the list defaults to empty. A client decodes the result at the type given by the function's ``ReturnType`` property. A function that produces no value returns an empty result, and a function whose value is null sets ``is_null`` on the result, the same flag any nullable return value uses. The function's ``HasReturnType`` property distinguishes no value from an empty collection, as both give an empty result. .. _communication-protocol-compile-function: CompileFunction ^^^^^^^^^^^^^^^ The ``CompileFunction`` procedure compiles a server side function, and returns nothing. The server otherwise compiles a function when it is first run, streamed or added as an event, on the game's main thread. Compiling a large function in advance keeps that time out of its first run. .. _communication-protocol-set-stream-rate: SetStreamRate ^^^^^^^^^^^^^ The ``SetStreamRate`` procedure sets the target update rate of a stream, in Hertz. Its arguments are the identifier of the stream and the rate, as a ``float``. A rate of zero, the default, updates the stream on every fixed update. While the game is paused with the server setting "Pause the server when the game pauses" turned off, the server updates once per rendered frame. Setting the rate of a stream that has already ended does nothing. An identifier the server never issued raises ``KRPC.ArgumentException``. A client with no stream server connection gets an ``InvalidOperationException``. .. _communication-protocol-remove-stream: RemoveStream ^^^^^^^^^^^^ The ``RemoveStream`` procedure removes a stream from the server. It takes a single argument -- the identifier of the stream to be removed. This is the identifier returned when the stream was added by calling :ref:`communication-protocol-add-stream` or :ref:`communication-protocol-add-function-stream`, or the stream identifier in an ``Event`` message. See :ref:`communication-protocol-streams` for more information on working with streams. Removing a stream that has already ended does nothing. An identifier the server never issued raises ``KRPC.ArgumentException``. A client with no stream server connection gets an ``InvalidOperationException``. .. _communication-protocol-service-description-message: Service Description Message --------------------------- The :ref:`GetServices procedure ` returns information about all of the services provided by the server. Details about a service are given by a ``Service`` message, with the format: .. literalinclude:: /communication-protocols/krpc.proto :language: protobuf :start-at: message Service { :end-before: message Procedure { The fields are: * ``name`` - The name of the service. * ``procedures`` - A list of ``Procedure`` messages, one for each procedure defined by the service. * ``classes`` - A list of ``Class`` messages, one for each :cs:attr:`KRPCClass` defined by the service. * ``enumerations`` - A list of ``Enumeration`` messages, one for each :cs:attr:`KRPCEnum` defined by the service. * ``exceptions`` - A list of ``Exception`` messages, one for each :cs:attr:`KRPCException` defined by the service. * ``structs`` - A list of ``Struct`` messages, one for each :cs:attr:`KRPCStruct` defined by the service. * ``documentation`` - Documentation for the service, as `C# XML documentation`_. * ``deprecated`` - Whether the service is deprecated. Deprecated services remain fully functional; this field is informational. * ``deprecated_reason`` - If the service is deprecated, the reason for its deprecation. May be empty. .. note:: See the :ref:`extending` documentation for more details about :cs:attr:`KRPCClass`, :cs:attr:`KRPCEnum`, :cs:attr:`KRPCStruct` and :cs:attr:`KRPCException`. Procedures ^^^^^^^^^^ Details about a procedure are given by a ``Procedure`` message, with the format: .. literalinclude:: /communication-protocols/krpc.proto :language: protobuf :start-at: message Procedure { :end-at: string deprecated_reason = 8; :append: } .. literalinclude:: /communication-protocols/krpc.proto :language: protobuf :start-at: message Parameter { :end-before: message Class { The fields are: * ``name`` - The name of the procedure. See :ref:`communication-protocol-procedure-names` for more information. * ``parameters`` - A list of ``Parameter`` messages containing details of the procedure's parameters, with the following fields: * ``name`` - The name of the parameter, to allow parameter passing by name. * ``type`` - The :ref:`type ` of the parameter. Its ``nullable`` field says whether null can be passed as the argument for this parameter. * ``has_default_value`` - Whether the parameter has a default value. When it is not set, the parameter is required and ``default_value`` and ``default_value_is_null`` are unset. * ``default_value`` - The default value of the parameter, :ref:`encoded using Protocol Buffer format `. Set only when ``has_default_value`` is set and ``default_value_is_null`` is not. A zero-length value is a valid default, for example an empty collection. * ``default_value_is_null`` - Whether the default value is null. Set only when ``has_default_value`` is set, in which case ``default_value`` is unset. The presence and nullability of the default value are given by these three fields as follows: .. list-table:: :header-rows: 1 * - Default value - ``has_default_value`` - ``default_value_is_null`` - ``default_value`` * - none (required parameter) - unset - unset - unset * - a value (including an empty collection) - set - unset - encoded bytes (may be zero-length) * - null - set - set - unset * ``return_type`` - The :ref:`return type ` of the procedure. If the procedure does not return anything its type is set to ``NONE``. Its ``nullable`` field says whether the procedure can return null. * ``game_scenes`` - The :ref:`game scenes ` that the procedure is available in. If this repeated field is empty, the procedure is available in all game scenes. * ``documentation`` - Documentation for the procedure, as `C# XML documentation`_. * ``deprecated`` - Whether the procedure is deprecated. Deprecated procedures remain fully functional; this field is informational. * ``deprecated_reason`` - If the procedure is deprecated, the reason for its deprecation. May be empty. Classes ^^^^^^^ Details about each :cs:attr:`KRPCClass` are specified in a ``Class`` message, with the format: .. literalinclude:: /communication-protocols/krpc.proto :language: protobuf :start-at: message Class { :end-before: message Enumeration { The fields are: * ``name`` - The name of the class. * ``documentation`` - Documentation for the class, as `C# XML documentation`_. * ``deprecated`` - Whether the class is deprecated. Deprecated classes remain fully functional; this field is informational. * ``deprecated_reason`` - If the class is deprecated, the reason for its deprecation. May be empty. Enumerations ^^^^^^^^^^^^ Details about each :cs:attr:`KRPCEnum` are specified in an ``Enumeration`` message, with the format: .. literalinclude:: /communication-protocols/krpc.proto :language: protobuf :start-at: message Enumeration { :end-before: message Exception { The fields are: * ``name`` - The name of the enumeration. * ``values`` - A list of ``EnumerationValue`` messages, indicating the values that the enumeration can be assigned. The fields are: * ``name`` - The name associated with the value for the enumeration. * ``value`` - The possible value for the enumeration as a 32-bit integer. * ``documentation`` - Documentation for the enumeration value, as `C# XML documentation`_. * ``deprecated`` - Whether the enumeration value is deprecated. Deprecated values remain fully functional; this field is informational. * ``deprecated_reason`` - If the enumeration value is deprecated, the reason for its deprecation. May be empty. * ``documentation`` - Documentation for the enumeration, as `C# XML documentation`_. * ``deprecated`` - Whether the enumeration is deprecated. Deprecated enumerations remain fully functional; this field is informational. * ``deprecated_reason`` - If the enumeration is deprecated, the reason for its deprecation. May be empty. .. _communication-protocol-structures: Structures ^^^^^^^^^^ A structure is a compound value with named fields, whose value on the wire is the values of those fields sent inline. A class sends an identifier for an object held on the server instead. Details about each :cs:attr:`KRPCStruct` are specified in a ``Struct`` message, with the format: .. literalinclude:: /communication-protocols/krpc.proto :language: protobuf :start-at: message Struct { :end-before: message Type { The fields are: * ``name`` - The name of the structure. * ``fields`` - A list of ``StructField`` messages, one for each field of the structure, in the order their values are encoded in. The fields are: * ``name`` - The name of the field. * ``type`` - The type of the field, as a :ref:`Type message `. A field may have any type a parameter or return value may have, including a class, a collection or another structure. Its ``nullable`` field says whether the field can be null. * ``documentation`` - Documentation for the field, as `C# XML documentation`_. * ``deprecated`` - Whether the field is deprecated. Deprecated fields remain fully functional; this field is informational. * ``deprecated_reason`` - If the field is deprecated, the reason for its deprecation. May be empty. * ``documentation`` - Documentation for the structure, as `C# XML documentation`_. * ``deprecated`` - Whether the structure is deprecated. Deprecated structures remain fully functional; this field is informational. * ``deprecated_reason`` - If the structure is deprecated, the reason for its deprecation. May be empty. A value of a structure type is encoded as a ``Tuple`` message whose items are the encoded values of the structure's fields, in the order the ``fields`` list gives them. This is the encoding of a tuple of the field types, so a client can use the codec it already has for tuples. The field names appear only in the definition above. One rule follows from that encoding: fields are only ever appended to a structure. A client generated against an older definition may receive more items than it has fields for, and ignores the extra items. Fewer items than its fields means the definitions do not match, and is an error. A field whose type is nullable carries a presence bool before its value. The bool is one byte, encoded as a ``BOOL`` value. The field's ordinary encoding follows it when the bool is true. A list element, a tuple item and a dictionary value carry the same bool, in the item of the ``List``, ``Tuple`` or ``DictionaryEntry`` message that holds them. For example, a structure whose first field is an ``SINT32`` and whose second is a nullable ``CLASS``:: Tuple.items[0] = 54 the first field, unchanged Tuple.items[1] = 01 07 present, then object id 7 Tuple.items[1] = 00 null A field that is not nullable is encoded as its value alone, and a null in one is an error. The presence bool is what separates a null field from a null structure: ``is_null`` on the enclosing ``Argument`` or ``ProcedureResult`` message applies to the structure value as a whole, and carries nothing about its fields. Exceptions ^^^^^^^^^^ Details about each :cs:attr:`KRPCException` are specified in an ``Exception`` message, with the format: .. literalinclude:: /communication-protocols/krpc.proto :language: protobuf :start-at: message Exception { :end-before: message Struct { The fields are: * ``name`` - The name of the exception type. * ``documentation`` - Documentation for the exception, as `C# XML documentation`_. * ``deprecated`` - Whether the exception is deprecated. Deprecated exceptions remain fully functional; this field is informational. * ``deprecated_reason`` - If the exception is deprecated, the reason for its deprecation. May be empty. .. _communication-protocol-procedure-names: Procedure Names --------------- Procedures names are CamelCase. Whether a procedure is a service procedure, class method, class property, and what class (if any) it belongs to is determined by its name: * ``ProcedureName`` - a standard procedure that is just part of a service. * ``get_PropertyName`` - a procedure that returns the value of a property in a service. * ``set_PropertyName`` - a procedure that sets the value of a property in a service. * ``ClassName_MethodName`` - a class method. * ``ClassName_static_StaticMethodName`` - a static class method. * ``ClassName_get_PropertyName`` - a class property getter. * ``ClassName_set_PropertyName`` - a class property setter. Only letters and numbers are permitted in class, method and property names. Underscores can therefore be used to split the name into its constituent parts. .. _communication-protocol-type: Type ---- The ``GetServices`` procedure returns type information about parameters, return values and others as ``Type`` messages. The format of these messages is as follows: .. literalinclude:: /communication-protocols/krpc.proto :language: protobuf :start-at: message Type { :end-before: // Collection data structures The ``code`` field specifies the type. ``NONE`` is used as the return type for procedures that do not return a value. For ``CLASS``, ``ENUMERATION`` and ``STRUCT`` types the ``service`` and ``name`` fields specify the service that defines the class, enumeration or structure and its name. For all other types these fields are empty. The fields of a structure are read from the :ref:`Struct message ` in the definition of the service that names it. For collection types the ``types`` repeated field will contain the sub-types: * ``TUPLE`` types contain 1 or more types in the ``types`` field. * ``LIST`` and ``SET`` types contain a single type in the ``types`` field. * ``DICTIONARY`` types contain a 2 types in the ``types`` field - the key and value types, in that order. For all other types the ``types`` field is empty. The ``nullable`` field says whether the position the type describes can hold null. It is a property of that position rather than of the type, so the same type is nullable in one place and not in another. The positions that can be nullable are a parameter, a return value, a default value, a :ref:`structure field `, a list element, a tuple item and a dictionary value. A dictionary key and a set element cannot. How the null itself is carried depends on the position. An argument, a result and a default value each have a flag of their own, ``Argument.is_null``, ``ProcedureResult.is_null`` and ``Parameter.default_value_is_null``. A value nested inside another value has no such flag, and carries a leading presence bool instead, in the form the :ref:`Structures ` section shows. .. _communication-protocol-game-scene: GameScene --------- The ``GetServices`` procedure returns information about which game scenes a procedure can be called from. These are returned as a repeated field containing ``GameScene`` enumeration values. If the procedure is available in all game scenes, this field is empty. The enumeration is defined as follows: .. literalinclude:: /communication-protocols/krpc.proto :language: protobuf :start-at: enum GameScene { :end-at: }; :dedent: The astronaut complex, mission control, research and development and administration scenes are facilities that open within the space center scene. .. _communication-protocol-proxy-objects: Proxy Objects ------------- kRPC allows procedures to create objects on the server, and pass a unique identifier for them to the client. This allows the client to create a *proxy* object for the actual object, whose methods and properties make remote procedure calls to the server. Object identifiers have type ``uint64``. When a procedure returns a proxy object or takes one as a parameter, the type code will be set to ``CLASS``. The ``is_null`` field of the ``ProcedureResult`` or ``Argument`` message signals a null object reference, as it does a null value of any other type. The object identifier is never used to represent null on the wire. .. _C# XML documentation: https://msdn.microsoft.com/en-us/library/aa288481%28v=vs.71%29.aspx