Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/FarlandsModdingTeam/TerbinProyect/llms.txt

Use this file to discover all available pages before exploring further.

Every service packet in Terbin is routed by a two-byte action key stored in an IdArray. The first byte comes from CodeServices (what kind of operation is being performed) and the second byte comes from CodeServicesSection (which domain or resource the operation targets). The two values are composed as:
var action = new IdArray((byte)CodeServices.Read, (byte)CodeServicesSection.Plugin);
The dispatcher matches this IdArray against the registered [TerbinExecutable] attributes to find the correct handler. Getting both bytes right is the only thing required to route a packet.

CodeServices enum (byte)

CodeServices represents the verb of a request — what the client wants to do. Values 1014 cover general service operations; values 250255 are CRUD aliases that mirror TerbinCRUD constants from TerbinLibrary.Protocol.
public enum CodeServices : byte
{
    Info      = 10,
    Alert     = 11,
    Execute   = 12,
    Dowload   = 13,
    Install   = 14,

    ReadAll   = TerbinCRUD.ReadAll,   // 250
    Duplicate = TerbinCRUD.Duplicate, // 251
    Create    = TerbinCRUD.Create,    // 252
    Read      = TerbinCRUD.Read,      // 253
    Update    = TerbinCRUD.Update,    // 254
    Deleted   = TerbinCRUD.Deleted,   // 255
}
ValueNameDescription
10InfoRequest informational data from a service.
11AlertPush an alert or notification to a service.
12ExecuteTrigger a service-level execution (e.g. launch a process).
13DowloadInitiate a download operation within the service.
14InstallInitiate an install operation within the service.
250ReadAllRetrieve all records from the target section. Aliases TerbinCRUD.ReadAll.
251DuplicateDuplicate an existing record. Aliases TerbinCRUD.Duplicate.
252CreateCreate a new resource. Aliases TerbinCRUD.Create.
253ReadRead a single resource. Aliases TerbinCRUD.Read.
254UpdateUpdate an existing resource. Aliases TerbinCRUD.Update.
255DeletedDelete a resource. Aliases TerbinCRUD.Deleted.

TerbinCRUD constants

The CRUD tail of CodeServices is backed by the TerbinCRUD enum in TerbinLibrary.Protocol. Use TerbinCRUD directly when you want to reference these operations independently of CodeServices:
public enum TerbinCRUD : byte
{
    ReadAll   = 250,
    Duplicate = 251,
    Create    = 252,
    Read      = 253,
    Update    = 254,
    Deleted   = 255,
}
ValueName
250ReadAll
251Duplicate
252Create
253Read
254Update
255Deleted

CodeServicesSection enum (byte)

CodeServicesSection represents the noun — the domain or subsystem that owns the handler. It is the second byte in the action IdArray.
public enum CodeServicesSection : byte
{
    Game          = 10,
    Plugin        = 20,
    PluginStorage = 21,
    Instances     = 30,
    FCM           = 40,
    Rute          = 50,
}
ValueNameDomain
10GameGame management — launching, registering, and duplicating game entries.
20PluginPlugin management — install, uninstall, list, and query plugins.
21PluginStoragePlugin storage layer — persistent plugin data and store manifests.
30InstancesGame instance management — create, read, list, and remove instances.
40FCMFirebase Cloud Messaging integration.
50RuteRoute/path management — resolve and persist game and asset paths.
The older CodeSubServices enum is [Obsolete]. It has the same values as CodeServicesSection and should not be used in new code. Migrate any CodeSubServices references to CodeServicesSection.

CodeServicesClient enum (byte)

CodeServicesClient is used for server-to-client progress packets. These are sent by the worker during long-running operations (downloads, installs) to update a progress bar on the client side.
public enum CodeServicesClient : byte
{
    SetMaxProgress = 10,
    SetBarProgress = 11,
}
ValueNameDescription
10SetMaxProgressSets the maximum value of the progress bar (the “total” steps).
11SetBarProgressUpdates the current progress bar value.

CodeTerbinProtocol enum (byte)

CodeTerbinProtocol occupies the reserved range 0–9 and is used exclusively for internal protocol-level messaging. Application-level handlers must not use these values as their action byte.
public enum CodeTerbinProtocol : byte
{
    Stop           = 0,
    Response       = 1,
    Load           = 2,
    Prolong        = 3,
    Solicit        = 4,
    ExceptionAlert = 5,

    [Obsolete] Create  = 6,
    [Obsolete] Read    = 7,
    [Obsolete] Update  = 8,
    [Obsolete] Deleted = 9,
}
ValueNameDescription
0StopSignals that communication should stop.
1ResponseMarks a packet as a response to a prior request (default ActionMethod in InfoResponse).
2LoadUsed to load or initialise a connection context.
3ProlongExtends the lifetime of an active session or keep-alive.
4SolicitSolicits memory or a resource from the worker.
5ExceptionAlertBroadcasts an exception alert over the protocol channel.
6Create ⚠️Obsolete — use TerbinCRUD instead.
7Read ⚠️Obsolete — use TerbinCRUD instead.
8Update ⚠️Obsolete — use TerbinCRUD instead.
9Deleted ⚠️Obsolete — use TerbinCRUD instead.
Create, Read, Update, and Deleted inside CodeTerbinProtocol are marked [Obsolete(error: true)] — they will cause a compile-time error if referenced. Use TerbinCRUD (or the aliased values in CodeServices) for all CRUD operations.

InternalErrors enum (ushort)

InternalErrors is the typed error code sent inside an InfoResponse.CreateInteralError payload. When a handler cannot complete its work it serialises one of these values into the response payload so the client can identify the exact failure without parsing a string message.
// Worker side — sending an internal error
return InfoResponse.CreateInteralError(request.IdRequest,
    BitConverter.GetBytes((ushort)InternalErrors.PluginNotExist));

// Client side — reading an internal error
ushort code = BitConverter.ToUInt16(response.Payload);
InternalErrors error = (InternalErrors)code;
if (error == InternalErrors.PluginNotExist)
    Console.WriteLine("Plugin does not exist on disk.");

General (0–99)

ValueNameDescription
11IdSoliciteErrorThe solicitation ID is invalid or could not be resolved.
12TODO_WIPPlaceholder — feature not yet implemented.
97IsUnknownUnknown error with no more specific code available.
98IsSuccesSentinel “success” value used in error-code return paths.
99IsCancelledThe operation was cancelled.

Game (100–199)

ValueNameDescription
101GameRuteNotExistThe configured game path/route does not exist on disk.
102GameAlredyExistAttempted to register a game that is already registered.
103GameNotContainExesThe game directory contains no executable files.
104GameNotLaunchThe game process failed to launch.

Plugin (200–299)

ValueNameDescription
201PluginNotConectCould not connect to the plugin source or registry.
202PluginOnDowloadAn error occurred during the plugin download.
203PluginNotSuchSpaceInsufficient disk space to store the plugin.
204PluginInvalidURLThe plugin download URL is malformed or unreachable.
205PluginNotExistThe requested plugin does not exist.
206PluginGetFailed to retrieve the plugin record.
207PluginGetPathFailed to resolve the plugin’s file system path.
208PluginOnSaveAn error occurred while saving the plugin data.
209PluginGetManifestFailed to read or parse the plugin manifest.
210PluginOnUnistallAn error occurred during plugin uninstall.
211PluginOnRemoveAn error occurred while removing plugin files.

Instances (300–399)

ValueNameDescription
301InstanceGetSizeErrorCould not calculate the size of the instance.
302InstanceNotExistThe requested instance does not exist.
303InstanceIsNotInstanceThe target path or object is not a valid Terbin instance.
304InstanceRegisterFailed to register the instance.
305InstanceUnregisterFailed to unregister the instance.
306InstanceCreateFailed to create a new instance.
307InstanceGetFailed to retrieve the instance record.

Rute (500–599)

ValueNameDescription
501RuteSerializeErrorFailed to serialize or deserialize a route entry.
502RuteAccesNullOrNotExistThe route record is null or does not exist.

BepInEx (600–699)

ValueNameDescription
601BepInExNotConectCould not connect to the BepInEx component or pipe.
602BepInExNotInstallBepInEx is not installed in the expected location.

Node (700–799)

ValueNameDescription
701NodeDinamiteA critical node-level failure occurred (explosive failure sentinel).

Handwritten (800–899)

ValueNameDescription
801HandwrittenCreateFailed to create a handwritten (manual) directory entry.
802HandwrittenRemoveFailed to remove a handwritten directory entry.
803HandwrittenGetFailed to retrieve a handwritten directory entry.

Manifest (900–999)

ValueNameDescription
901ManifestCreateFailed to create a manifest file.
902ManifestRemoveFailed to remove a manifest file.
903ManifestGetFailed to read or parse a manifest file.
904ManifestUpdateFailed to write an updated manifest file.

Zip (1000–1099)

ValueNameDescription
1001ZipExtractErrorA non-exception extraction failure occurred.
1002ZipExtractExceptionAn exception was thrown during zip extraction.
1003ZipDeletedTempExceptionAn exception occurred while deleting the temporary zip file.

Putting it all together

// Build a "Read Plugin" action key
var action = new IdArray(
    (byte)CodeServices.Read,           // 253
    (byte)CodeServicesSection.Plugin   // 20
);

// Dispatch the packet
PacketRequest packet = PacketRequest.Create(action, payload);
InfoResponse response = await communicator.Communicate(action, payload);

// Check for an internal error
if (response.Status == CodeStatus.InternalWorkerError && response.Payload.Length >= 2)
{
    var errorCode = (InternalErrors)BitConverter.ToUInt16(response.Payload);
    Console.WriteLine($"Handler reported: {errorCode}"); // e.g. PluginNotExist
}

Build docs developers (and LLMs) love