Robust Toolbox Documentation

repository·master·Indexed 20 days ago

https://github.com/space-wizards/robusttoolbox

A specialized game engine designed for Space Station 14, supporting both singleplayer and multiplayer architectures. It serves as the foundational engine layer for game content. The documentation covers the SS14 map file format (YAML), server status HTTP configuration, licensing, CEF helper custom scheme registration, and various client console commands for entity debugging and management.

Tokens
42.3K
Snippets
238
Records
282
Agent score
71%

What's inside Robust Toolbox

  1. Understand the purpose of Robust Toolbox

    master

    Robust Toolbox is a game engine designed primarily for Space Station 14. While its primary use case is SS14, it is being developed to support both singleplayer and multiplayer projects.

    Important Note for Developers: This repository contains the engine only. It does not start on its own and requires a content repository (such as the Space Station 14 content repo) to function. It serves as the foundational layer, similar to how BYOND functions for Space Station 13.

  2. Structure the `grids` and `chunks` sections

    master

    The grids section is an ordered sequence of grid data. Each grid contains:

    Grid Settings

    • tilesize: Integer (meters) representing the length of one side of a tile.
    • chunksize: Integer representing the tile dimensions of a chunk (e.g., x means an x by x tile region).
    • snapsize: Float representing the snap grid size.

    Chunk Data

    Each grid contains a chunks sequence. Each entry is a mapping with:

    • ind: The chunk index.
    • tiles: A Base64 encoded binary array of tile data.

    Tile Data Format: Tiles are stored in row-major order without gaps. Each tile is exactly 4 bytes (ushort for Tile ID, ushort for metadata, little-endian). Total chunk size in bytes is chunksize * chunksize * 4.

  3. Understand the SS14 Map File Format

    master

    SS14 map files are single-document YAML files encoded in UTF-8. The root node is a mapping containing several top-level sections: meta, tilemap, grids, and entities.

    Key characteristics:

    • Blueprints: A map file containing exactly one grid is considered a blueprint.
    • Encoding: Numeric data uses CultureInfo.InvariantCulture. Tile data is little-endian.
    • Units: Distances and coordinates are in meters; angles are in radians.
  4. Understand the Authentication Handshake protocol

    master

    The client and server communicate via Lidgren.Network. The authentication process follows a pattern similar to Minecraft's protocol to establish a secure, encrypted session. The server can be configured to require authentication, optionally allow it, or disable it entirely.

    Handshake Flow

    1. Client Initiation: Client sends MsgLoginStart containing the username, authentication preference, and a request for the server's public encryption key (if not already possessed).
    2. Server Decision:
      • If the server allows guest access, it skips to MsgLoginSuccess.
      • If authentication is required/allowed, the server sends MsgEncryptionRequest containing a random verify token and the server's public encryption key.
    3. Client Authentication:
      • The client generates a 32-byte random secret.
      • The client computes an SHA-256 hash of the secret + server's public key.
      • The client POSTs this hash to api/session/join (including the login token in the Authorization header) to verify with the auth server.
      • The client sends MsgEncryptionResponse containing the encrypted shared secret, the encrypted verify token, and the client's account GUID.
    4. Server Verification:
      • The server decrypts the token and secret using its private key.
      • The server validates the verify token.
      • The server performs a GET request to api/session/hasJoined?hash=<hash>&userId=<userId> to confirm the client's authentication with the auth server.
    5. Session Establishment: Upon success, the server sends MsgLoginSuccess with the assigned username/userID. All subsequent messages are encrypted using the shared secret.

    Technical Implementation Details

    • Encryption Type: Game packets are encrypted using AEAD XChaCha20-Poly1305 via libsodium.
    • Key Exchange: Public/private key operations use Sealed Boxes.
    • Key Discovery: The server generates a new encryption key on every startup, which is exposed via the status API at /info.
  5. Reference the `entities` section and UIDs

    master

    The entities section is an indexed list of all entities on the map. An entity declaration functions like a prototype.

    • type: Specifies the prototype.
    • components: List of component overrides.
    • uid: A unique numerical identifier used for cross-referencing.

    Cross-referencing IEntity

    When an entity references another IEntity via a UID:

    • If the referenced entity is included in the map, it is serialized as its integer uid.
    • If the referenced entity is not included in the map (e.g., it is on a different grid), it is serialized as YAML null.
  6. Enable the SS14 Status HTTP server

    master

    An SS14 server can host a simple HTTP server to allow external software (such as websites or bots) to fetch server status information.

    To enable this feature, set the status.enabled configuration variable to true. You can specify the binding address using the bind variable.

    Recommendation: It is recommended to leave the bind address as localhost and change the port number if running multiple servers on one machine. This server is intended to be used behind a reverse proxy (like Nginx or Apache) as it does not support modern features like SSL or gzip.

    status.enabled: true
    bind: localhost
  7. Access the '$value' variable in Reduce blocks

    master

    When using the Reduce command, the reducer block has access to a special local variable named $value. This variable is automatically updated by the command to represent the current element being pulled from the piped input stream during each iteration of the reduction.

    This allows you to write reduction logic that references the current item being processed without needing to pass it through an explicit parameter, provided the block is parsed using the ReduceBlockParser logic.

  8. Use the emplace command to process piped values

    master

    The emplace command is a generic CLI tool used to take a value (or a collection of values) from a pipe and execute a code block for each one. It is primarily used to transform or act upon entities or sessions within a Toolshed context.

    Usage Patterns

    1. Single Value: Takes one input from the pipe and executes the block once.
    2. Collection of Values: Takes an IEnumerable<T> from the pipe and executes the block for every item in the collection. If errors occur during iteration, the process stops.

    Available Local Variables

    When using emplace, the command injects specific local variables into the block's scope based on the type of the piped input. These variables are read-only.

    If the piped input is an EntityUid:

    • value: The current EntityUid.
    • wx: The X coordinate of the entity's world position.
    • wy: The Y coordinate of the entity's world position.
    • proto: The ID of the entity's prototype (string).
    • desc: The entity's description (string).
    • name: The entity's name (string).
    • paused: Whether the entity is paused (boolean).

    If the piped input is an ICommonSession:

    • value: The current session object.
    • ent: The EntityUid attached to the session.
    • name: The session's name (string).
    • userid: The session's NetUserId.

    Note: The variable value is always available and represents the current item being processed.

    # Example: Emplace a block over a list of entities (conceptual CLI syntax)
    # entities | emplace { 
    #   # Inside here, 'value' is the EntityUid
    #   # 'name' and 'wx' are available automatically
    #   print("Processing {name} at {wx}")
    # }
  9. Use arithmetic commands for scalar and vector operations

    master

    The Toolshed provides a suite of CLI commands for performing arithmetic operations. These commands support both scalar values and collections (sequences) of values. Many commands have a specific variant for applying a single value to every element in a collection (vector-style operations).

    Supported Operations

    CommandOperationDescription
    +AdditionAdds two scalars or zips two collections
    +/Add VectorAdds a single scalar to every element in a collection
    -SubtractionSubtracts two scalars or zips two collections
    -/Sub VectorSubtracts a single scalar from every element in a collection
    *MultiplicationMultiplies two scalars or zips two collections
    */Mul VectorMultiplies every element in a collection by a single scalar
    /DivisionDivides two scalars or zips two collections (returns 0 if divisor is 0)
    //Div VectorDivides every element in a collection by a single scalar (returns 0 if divisor is 0)
    %ModulusComputes the remainder of two scalars or zips two collections
    %/Mod VectorComputes the remainder of every element in a collection by a single scalar
    MinMinimumReturns the minimum magnitude of two values
    MaxMaximumReturns the maximum magnitude of two values
    NegNegationNegates a scalar or every element in a collection
    AbsAbsoluteReturns the absolute value of a scalar or every element in a collection
  10. Deploy Prometheus and Grafana via Docker Compose

    master

    Use the provided docker-compose.yml to set up a monitoring stack consisting of Prometheus for metrics collection and Grafana for visualization. Both services use host network mode, meaning they will bind directly to the host's network interfaces.

    Prometheus Configuration

    • Image: prom/prometheus
    • Configuration: The Prometheus configuration file must be located at ./prometheus.yml relative to the compose file and will be mounted to /etc/prometheus/prometheus.yml inside the container.

    Grafana Configuration

    • Image: grafana/grafana
    • Persistence: Grafana data is persisted using a named volume grafana_data mounted to /var/lib/grafana.
    • Provisioning: Dashboard and data source provisioning is handled via a named volume grafana_provisioning mounted to /etc/grafana/provisioning/.
    version: "3.4"
    
    services:
      prometheus:
        image: prom/prometheus
        network_mode: host
        volumes:
          - ./prometheus.yml:/etc/prometheus/prometheus.yml
    
      grafana:
        image: grafana/grafana
        network_mode: host
        volumes:
          - grafana_data:/var/lib/grafana
          - grafana_provisioning:/etc/grafana/provisioning/
    
    volumes:
      grafana_data:
      grafana_provisioning: