Getting Started


Adding TCE to your project is extremely easy. Simply grab the latest archive from our public releases page and extract the following files to your Assets/ folder:

  • ConsensusEngine.dll

    • Required: the C# bindings assembly for TCE

  • tce_ffi.dll

    • Windows shared library for Tashi Consensus Engine

    • Required for Windows applications; may be omitted if Windows support is not required.

    • x86-64 (AMD64) Only

  • libtce_ffi.dylib

    • MacOS shared library for Tashi Consensus Engine

    • Required for MacOS applications; may be omitted if MacOS support is not required.

    • Multi-arch: x86-64 (AMD64) and Aarch64 (ARMv8)


    • Linux shared library for Tashi Consensus Engine

    • Required for Linux applications; may be omitted if Linux support is not required.

    • x86-64 (AMD64) only

Unity should load ConsensusEngine.dll automatically.

Initializing TCE

Initialization of Tashi Consensus Engine involves a few different steps:

  • (Optional) Initializing Logging

  • Generating a secret key or restoring one from a file.

  • Initializing PlatformConfig

  • Constructing an address book or obtaining the public key and IP address of a node in a running session.

  • Constructing an instance of the Platform class and starting the TCE session.

(Optional) Initialize Logging

TCE emits logs detailing its internal operation which may be useful in debugging issues.

The C# bindings expose this through the Logger class which allows you to set delegates for receiving these log messages. You can hook this up to the logging methods of Unity's Debug class to see log messages from TCE in the console in the Unity editor:

Logger.Init(Debug.Log, Debug.LogWarning, Debug.LogError);

You'll also want to set a log filter as there are multiple components in TCE that log at different verbosity levels. As a default, we recommend:


If you contact support with an issue, you may be asked to change this filter to get additional information.

Generate or Restore a Secret Key

The Tashi Consensus algorithm uses Elliptic Curve Digital Signature Algorithm (ECSDA) keys to identify peers. ECDSA signatures are a core component of the consensus algorithm, which uses their cryptographic unpredictability to ensure fairness.

The first step of initializing TCE is to generate or construct an ECDSA keypair (a secret key and a public key; the public key is mathematically derived from the secret key and automatically managed by the SecretKey class). You may either choose to generate a new keypair for every session (ephemeral keypair), or use a persistent keypair to identify a player across multiple sessions. If using a persistent keypair, the secret key must be kept secure as otherwise it may be used to impersonate the player.

By default, the PlatformConfig class's constructor will automatically generate a new secret key if one is not provided.

Otherwise, you can use SecretKey.Generate() to generate a new secret key, or .FromDer() to restore a previously generated secret key that was encoded with .AsDer(). Methods for securely saving and restoring a secret key are out of scope for this document.

Initialize PlatformConfig

The PlatformConfig class is the primary way to configure TCE.

This class has many fields which will let you fine-tune TCE for different performance targets, but to begin with we recommend leaving most of them at their defaults.

A couple fields of note are BindAddress and SecretKey. For the latter, you should already have decided in the previous step whether you're going to generate a new key or use an existing one.

The BindAddress field is the address to bind for the UDP socket that will be used for all TCE's communications. Pass new IPEndPoint(IPAddress.Any, 0) to bind to any network interface and have the operating system choose a UDP port for you (ephemeral port). You can query the bound port later with Platform.GetBoundAddress().

On Windows, a socket bound to IPAddress.Any ( will not receive traffic from loopback addresses ( You need to either bind to explicitly, or use your LAN IP address when connecting.

As of writing, TCE only supports IPv4 addresses.

If you plan on advising players to use manual port forwarding to resolve connection issues instead of using Tashi Relay, you should bind the same port every time. We recommend choosing a port number greater than 1024 that is not already registered with the IANA. Avoid port numbers higher than 32768 as those may fall in the range used by the operating system for ephemeral ports (49152 if you don't plan to support Linux).

Construct the Address Book

To begin a session, TCE needs to know who the other peers are and how to reach them (i.e. their IP address). The structure containing this knowledge is called the address book. The C# bindings encode the address book as a List<AddressBookEntry>.

TCE can either start with a complete address book, in which case the address book must be the same across all peers or else the session may fail to start, or it can start with a single peer, from whom it will fetch the complete address book for a running session. This is controlled by the joiningRunningSession flag to Platform.Start().

There is currently no bespoke service for session management, but you can use a service like Unity Lobby to help a player find or create a lobby and share session details with joining players.

For most intents and purposes, you can simply construct your session's address book as a List<DirectAddressBookEntry>.

Start TCE

The Platform class has a few different subclasses for different applications, but there are two primary ones for general use.


This subclass of Platform is for sessions that will not be using Tashi Relay.

To start, simply pass your PlatformConfig to the public constructor, and then call .Start() with your address book. Pass true for joiningRunningSession if the address book is incomplete and should be downloaded from a peer already in the session.


This subclass of Platform is concerned with configuring TCE to use a Tashi Relay session (see Networking and Tashi Relay on the previous page for details).

If you want to start a new session, use .StartRelaySession() which is similar to .Start() but takes a few new parameters. You should have the relay base URL and API key to use after registering at the link in the above section discussing Tashi Relay.

Besides the address book for the session, the other two parameters are callbacks invoked with the result of the call to allocate a relay session. Note that these callbacks will be invoked from a different thread:

  • The onSuccess callback will receive the relay allocation data, which you will need to pass to the other peers in the session through a side channel, such as Unity Lobby.

  • The onError callback will be invoked if a session could not be allocated; the most likely reasons for an error occurring include but are not limited to:

    • The number of peers in the address book is larger than the session size limit for your API key;

      • If this or the session limit error occurs, you may need to purchase a higher service tier.

    • The concurrent session limit for your API key has been reached, or:

    • The Tashi Relay service is currently unavailable.

To join a running session using Tashi Relay, use .JoinRelaySession(), which takes the address book as well as the relay allocation data which should have been provided by the creator of the session.

Pass Session Information to Peers

Once TCE is running, and optionally a Tashi Relay session has been allocated, the next step is to pass the session information to the other peers that will be joining so that they can connect.

At minimum, two things are required, which will form your entry in the peer's address book:

  • Your ECSDA public key, which can be accessed via the SecretKey.PublicKey getter.

    • A portable binary encoding can be accessed via PublicKey.Der which can then be decoded using the PublicKey(byte[] der) constructor. By convention, we like to convert this to a hex string, but this is optional.

  • Your publicly reachable socket address (IP address and port; .NET calls this IPEndPoint).

    • The bound IP address can be retrieved via Platform.GetBoundAddress(), but this may not be a real socket address if you used IPAddress.Any to bind.

    • If behind Network Address Translation (NAT), the local machine may not know the public IP address it can be reached at. This normally requires administrative access to your broadband router or a third party service to tell you what your IP is.

    • If using Tashi Relay or a publicly accessible peer as a relay (see Networking and Tashi Relay on the previous page), then the declared socket address doesn't matter as much. It can be a LAN address or an arbitrarily chosen one. This can also be used to hide players' true IP address from one another for privacy reasons (you'll also want to set EnableHolePunching to false in PlatformConfig as the hole punching protocol involves sharing real IP addresses).

Additionally, if you allocated a Tashi Relay session, the allocation data will also need to be passed to other peers.

How to actually coordinate with other peers is out of scope for this document. You may wish to use a third-party service like Unity Lobby.

Last updated