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 byte that crosses a Terbin named pipe is organized into discrete packets. Each packet carries a fixed-size header, a variable-length action key, and a variable-length payload. The TerbinProtocol static class defines the constants that govern packet sizing, fragmentation boundaries, and timeout behaviour. Understanding these constants is the foundation for building reliable Terbin services.

TerbinProtocol Constants

ConstantValueMeaning
MAX_PLD0xFFF0 (65,520)Maximum payload bytes in a single packet. Payloads larger than this are automatically fragmented.
FRAGMENT_IN0xFFAA (65,450)The exact slice size used when splitting an oversized payload into fragment chunks.
ORDER_SINGLE0 (ushort.MinValue)The OrderRequest value that marks a complete, unfragmented packet.
FIRST_PACKET1The OrderRequest index of the first fragment in a multi-packet sequence.
FINAL_PACKET65535 (ushort.MaxValue)The OrderRequest value that marks the last fragment, triggering reassembly.
MAXIMUS_RESPONSE_TIME8Default timeout in seconds for Communicate() to wait for a response.
RESERVE_PROTOCOL9The first 10 action bytes (0–9) are reserved for internal protocol operations.
RESERVE_MEMORY9The first 10 memory slot IDs (0–9) are reserved for the protocol.
LENGTH_ARRAYThreeQuartersInt.Size (3)Bytes consumed by the array-length prefix in every serialized array.

Packet Anatomy

Every transmitted unit is a serialized PacketRequest struct, which contains a Header, an IdArray, and a byte payload:
┌─────────────────────────────────────────────────────────────────────┐
│  PacketRequest (wire format)                                        │
│                                                                     │
│  ┌────────────────────────────── Header (7 bytes) ───────────────┐  │
│  │  IdRequest    : ushort  (2 bytes) — unique request correlator  │  │
│  │  OrderRequest : ushort  (2 bytes) — fragment sequence index    │  │
│  │  Status       : short   (2 bytes) — CodeStatus value           │  │
│  │  IdMemory     : byte    (1 byte)  — memory slot ID             │  │
│  └───────────────────────────────────────────────────────────────┘  │
│                                                                     │
│  ┌────────────────────────────── IdArray ────────────────────────┐  │
│  │  Length       : byte    (1 byte)  — number of action bytes     │  │
│  │  ActionBytes  : byte[]  (N bytes) — action key sequence        │  │
│  └───────────────────────────────────────────────────────────────┘  │
│                                                                     │
│  ┌────────────────────────────── Payload ────────────────────────┐  │
│  │  LengthPrefix : ThreeQuartersInt (3 bytes)                     │  │
│  │  Data         : byte[]  (0..MAX_PLD bytes)                     │  │
│  └───────────────────────────────────────────────────────────────┘  │
│                                                                     │
│  Each packet is framed on the wire with a 2-byte length prefix     │
│  written by StreamWriteStruct before the serialized body.          │
└─────────────────────────────────────────────────────────────────────┘

Header Fields

IdRequest
ushort
Correlation ID linking a request to its response. Auto-generated by MiniID.NewS if not provided explicitly. Enforced to ≥ 1 (a value of 0 is internally bumped to 1).
OrderRequest
ushort
Fragment sequence number. See the fragmentation section below for how values are assigned.
Status
CodeStatus (short)
The CodeStatus sent with this packet. On the outbound side this is the caller’s intent; on the inbound side it drives dispatcher behaviour.
IdMemory
byte
Identifies which TerbinMemory slot is accumulating fragments for this request. Set to CodeTerbinMemory.NotAsign for single-packet transmissions.
OrderRequest = 0 (ORDER_SINGLE) means the packet contains a complete, self-contained payload. Values 1..N are fragment indices for intermediate chunks. A value of 65535 (FINAL_PACKET) marks the last chunk and triggers the receiver to reassemble all stored fragments from the memory slot.

Single-Packet Flow (payload ≤ MAX_PLD)

When pPayload.Length <= TerbinProtocol.MAX_PLD, the internal send() method routes to HandleSendSigle:
public async Task HandleSendSigle(
    IdArray pActionMethod,
    byte[] pPayload,
    ushort pIdRequest,
    CodeStatus pStatus)
This builds a single PacketRequest with OrderRequest = ORDER_SINGLE and IdMemory = CodeTerbinMemory.NotAsign, then enqueues it for the background send loop. The receiver detects OrderRequest != FINAL_PACKET in TerbinMemoryHelper.TryGetMemoryStream and passes the payload through directly.

Fragmented-Packet Flow (payload > MAX_PLD)

Large payloads go through HandleSendFragment, which executes a multi-step handshake:
1

CheckExecution Handshake

A Communicate() call is made with CodeStatus.CheckExecution and an empty payload. The remote dispatcher responds with CodeStatus.Succes if a handler for that action is registered, or an error otherwise. This prevents the sender from allocating memory and streaming fragments toward an action that cannot handle them.
2

Solicit a Memory Slot

SoliciteRequestMemory() sends a packet with action CodeTerbinProtocol.Solicit and IdMemory = CodeTerbinMemory.New. The remote TerbinExecutor.Solicit handler calls TerbinMemoryManager.GetFreeStore() and replies with the assigned slot ID as the payload.
3

Stream Fragments via Load

The payload is sliced in FRAGMENT_IN-byte (65,450 bytes) chunks. Each chunk is sent with action CodeTerbinProtocol.Load and an incrementing OrderRequest starting at FIRST_PACKET (1). The remote TerbinExecutor.Load handler stores each chunk in the assigned TerbinMemory slot.
4

Final Packet

The remaining tail of the payload (≤ MAX_PLD) is sent with the original action key, OrderRequest = FINAL_PACKET, and the assigned IdMemory. On receipt, TerbinMemoryHelper.TryGetMemoryStream detects FINAL_PACKET, calls TerbinMemoryManager.TryGetResult to reassemble all stored fragments, appends the final chunk’s payload, releases the memory slot, and delivers the complete data to the OnRecive handler.

CodeTerbinProtocol Enum

These values occupy the reserved action bytes (0–9) and are used exclusively by the protocol itself:
ValueBytePurpose
Stop0Reserved — stop signal
Response1Standard response routing; resolves pending Communicate() awaiters
Load2Streams a fragment into a memory slot
Prolong3Resets the timeout timer for an in-flight request
Solicit4Requests a new memory slot ID from the remote side
ExceptionAlert5Carries exception details back to the caller (planned)

CodeTerbinMemory Enum

Used in the Header.IdMemory field to communicate memory slot semantics:
ValueByteMeaning
None0No memory state
NotAsign1No slot assigned; packet is self-contained
New2Request a new slot allocation
Undefined3Default uninitialized state
ErrorRecuperate4Recovery error placeholder

CodeStatus Enum

CodeStatus is a short-backed enum inspired by HTTP status codes. It is carried in Header.Status and controls how the dispatcher and communicator respond to each packet.
ValueCodeDescription
NotAsign-1Uninitialized or unassigned status; used internally as a default sentinel value
ValueCodeDescription
Info100Informational signal
Alert101Alert signal
Exception102Exception notification
IsCancelled103Operation was cancelled
ValueCodeDescription
Succes200Operation completed successfully
ValueCodeDescription
Execute300Normal execution request — the most common outbound status
ExecuteInternal301Internal execution variant
CheckExecution303Preflight: check handler exists without executing
CancelByRequest304Cancel a specific in-flight request
CancelByAction305Cancel all executions for a given action key
ValueCodeDescription
ClientError400Generic client error
BadRequest401Malformed request
NotFound404Generic not-found
ActionNotFound440No handler registered for the action key
ActionNotInitiated442Cancel requested but action never started
AccessDenied450Access denied
ErrorSoliciteMemory470Failed to allocate a memory slot
AlreadyExistsPetition471Duplicate pending request ID
ValueCodeDescription
InternalWorkerError500Generic internal error
ExecutionException501Handler threw an exception — payload contains ExceptionDTO
ErrorNotPayload502Expected payload was missing
SerializeError503Serialization failure
AccesNullOrNotExist504Null access or missing resource
OverMaximumTime550Communicate() timed out waiting for a response
OverMaximunPacket551Fragment count exceeded ushort.MaxValue - 1
ErrorGetPaylaodMemory571Failed to read from the memory slot
ErrorReleaseMemory572Failed to release the memory slot after assembly

Build docs developers (and LLMs) love