{"id":19308550,"url":"https://github.com/dcronqvist/arachne","last_synced_at":"2026-05-16T00:05:30.567Z","repository":{"id":132693409,"uuid":"532676389","full_name":"dcronqvist/Arachne","owner":"dcronqvist","description":"🕷️ authoritative server protocol and .NET library for games using udp","archived":false,"fork":false,"pushed_at":"2023-06-04T15:09:34.000Z","size":165,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-01-06T01:29:11.633Z","etag":null,"topics":["csharp","dotnet","game-networking","gamedev","games","multiplayer","multiplayer-games","networking","udp"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dcronqvist.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-09-04T22:47:14.000Z","updated_at":"2024-12-15T19:11:58.000Z","dependencies_parsed_at":null,"dependency_job_id":"5a732de1-bdd0-488d-b14a-e730cac841f3","html_url":"https://github.com/dcronqvist/Arachne","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dcronqvist%2FArachne","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dcronqvist%2FArachne/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dcronqvist%2FArachne/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dcronqvist%2FArachne/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dcronqvist","download_url":"https://codeload.github.com/dcronqvist/Arachne/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240409852,"owners_count":19796797,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["csharp","dotnet","game-networking","gamedev","games","multiplayer","multiplayer-games","networking","udp"],"created_at":"2024-11-10T00:15:21.992Z","updated_at":"2025-11-17T00:01:26.291Z","avatar_url":"https://github.com/dcronqvist.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 🕷️ Arachne [![.NET Tests](https://github.com/dcronqvist/Arachne/actions/workflows/tests.yml/badge.svg)](https://github.com/dcronqvist/Arachne/actions/workflows/tests.yml)\r\n\r\n## Protocol\r\n\r\nThe Arachne protocol is a simple protocol that allows for clients to connect to an authoritative server using some kind of identification, and will then allow the client and server to communicate with each other. This protocol is very simple and is primarily designed to be used in games, but could potentially be used in other applications as well.\r\n\r\nIt uses UDP for all communication and allows for 4 different ways of communication:\r\n\r\n- **Unreliably**, fastest way of communication, but packets can be lost.\r\n\r\n- **Reliably**, slower way of communication, but packets will never be lost.\r\n\r\nNo regard for order is taken for ANY packets sent, so the order of received packets is not guaranteed to be the same as the order of sent packets.\r\n\r\n### Protocol packets\r\n\r\nThe protocol consists of a few different packets, which are mostly used for connection intialization, and connection termination.\r\n\r\n#### Protocol packet types and channels\r\n\r\nThe protocol uses 4 different channels and has 8 different packet types. Both the channel and packet type are specified as a single bit packed byte in the packet header. The channel is specified in the high 4 bits, and the packet type is specified in the low 4 bits.\r\n\r\nThe 4 different channels are:\r\n\r\n```\r\nUnreliable  = 0x00\r\nReliable    = 0x10\r\n```\r\n\r\nThe 8 different packet types are:\r\n\r\n```\r\nConnection request              = 0x00\r\nConnection challenge            = 0x01\r\nConnection challenge response   = 0x02\r\nConnection response             = 0x03\r\nConnection keep alive           = 0x04\r\nApplication data                = 0x05\r\nConnection termination          = 0x06\r\nConnection termination ack      = 0x07\r\nServer info request             = 0x08\r\nServer info response            = 0x09\r\n```\r\n\r\nSo, a packet header with a first byte of `0x00` would be a `Connection request` packet on the `Unreliable` channel. A packet header with a first byte of `0x15` would be an `Application data` packet on the `Reliable` channel.\r\n\r\nThe entire packet header looks like the following:\r\n\r\n```\r\n[channel + packet type] (1 byte, high 4b = channel, low 4b = type)\r\n[sequence number]       (8 bytes)\r\n[sequence ack]          (8 bytes)\r\n[ack bits]              (4 bytes)\r\n...\r\n[data]                  (variable length)\r\n```\r\n\r\nA total of 21 bytes of overhead is added to each packet, to allow for the Arachne protocol to function properly.\r\n\r\n### Connection initialization\r\n\r\nThere 2 different ways to allow for a connection to be established.\r\n\r\n- **No authentication** - This is the simplest way of connecting, and is used when the server does not require any kind of authentication from the client. The client will simply send a `CR` packet to the server, and the server will respond with a `CRS` packet either allowing or denying the connection.\r\n\r\n- **With authentication** - This is a more complex way of connecting, and is used when the server requires some kind of authentication from the client. The client will send a `CR` packet to the server, and the server will respond with a `CH` packet, which will contain a challenge for the client. The client will then respond with a `CHR` packet, which will contain the challenge response. The server will then respond with a `CRS` packet either allowing or denying the connection. The authentication method is up to the developer to implement, however, there are some examples provided if needed.\r\n\r\n#### **Connection Request (CR)**\r\n\r\nThis packet is sent by the client to the server, and is used to request a connection to the server. The server will then respond with a Connection Response packet.\r\n\r\nIf the given `protocol id` and `protocol version` is not supported by the server, the server will respond with a `CRS` packet with response code `0x01` (unsupported protocol).\r\n\r\n```\r\n[header]            (21 bytes) (always sent on the Reliable channel)\r\n...\r\n[protocol id]       (4 bytes)\r\n[protocol version]  (4 bytes)\r\n```\r\n\r\n#### **Connection Challenge (CH)**\r\n\r\nThis packet is sent by the server to the client, and is used to challenge the client to prove that it is allowed to connect. The client will then respond with a `CHR` packet.\r\n\r\nThe packet can contain anything that the developer so chooses, and it is up to the developer to implement this.\r\n\r\n```\r\n[header]            (21 bytes) (always sent on the Reliable channel)\r\n...\r\n[challenge length]  (4 bytes)\r\n[challenge]         (variable length)\r\n```\r\n\r\n#### **Connection Challenge Response (CHR)**\r\n\r\nThis packet is sent by the client to the server, and is used to respond to the challenge that the server sent. The server will then respond with a `CRS` packet.\r\n\r\n```\r\n[header]            (21 bytes) (always sent on the Reliable channel)\r\n...\r\n[response length]   (4 bytes)\r\n[response]          (variable length)\r\n```\r\n\r\n#### **Connection Response (CRS)**\r\n\r\nThis packet is sent by the server to the client, and is used to respond to a Connection Request packet. This response will contain a code that will indicate the outcome of the connection request.\r\n\r\n```\r\n[header]        (21 bytes) (always sent on the Reliable channel)\r\n...\r\n[response code] (1 byte)\r\n[client id]     (8 bytes)\r\n```\r\n\r\n### During connection packets\r\n\r\n#### **Connection Keep Alive (KA)**\r\n\r\nThis packet is sent by the client to the server, and is used to keep the connection alive. The server will not respond to this packet, it is only for the server to know if the client is still alive and connected.\r\n\r\n`KA` packets are sent every 5 seconds by default, but this can be changed by the developer.\r\n\r\nIf no `KA` packets are received from a connected client within a specified timeout, the server will consider the client to be disconnected and will remove the client from its list of connected clients.\r\n\r\n```\r\n[header] (21 bytes) (always sent on the Unreliable channel)\r\n...\r\n(no data, packet type enough)\r\n```\r\n\r\n#### **Application Data (AD)**\r\n\r\nThis packet can be sent by either the client or the server, and is used to send application data to the other party. The packet can contain any kind of data that the developer so chooses.\r\n\r\n```\r\n[header]        (21 bytes) (sent on whichever channel the developer chooses)\r\n...\r\n[data length]   (4 bytes)\r\n[data]          (variable length)\r\n```\r\n\r\n### Connection termination\r\n\r\n#### **Connection Termination (CT)**\r\n\r\nThis packet is sent by either the client or the server, and is used to terminate the connection. The packet can contain a reason for the termination. The other party should then respond with a `CTA` packet, to acknowledge the termination.\r\n\r\n```\r\n[header]        (21 bytes) (always sent on the Reliable channel)\r\n...\r\n[reason length] (4 bytes)\r\n[reason string] (variable length, UTF-8 encoded)\r\n```\r\n\r\n#### **Connection Termination Acknowledgement (CTA)**\r\n\r\nThis packet is sent by either the client or the server, and is used to acknowledge the termination of the connection.\r\n\r\n```\r\n[header] (21 bytes) (always sent on the Reliable channel)\r\n...\r\n(no data, packet type enough)\r\n```\r\n\r\n### Server info\r\n\r\n#### **Server Info Request (SIR)**\r\n\r\nThis packet is sent by the client to the server, and is used to request information about the server. The server will then respond with a `SIRS` packet.\r\n\r\n```\r\n[header] (21 bytes) (always sent on the Unreliable channel)\r\n...\r\n(no data, packet type enough)\r\n```\r\n\r\n#### **Server Info Response (SIRS)**\r\n\r\nThis packet is sent by the server to the client, and is used to respond to a `SIR` packet. This response will contain information about the server.\r\n\r\n```\r\n[header]        (21 bytes) (always sent on the Unreliable channel)\r\n...\r\n[info]          (variable length, raw bytes)\r\n```\r\n\r\nThe `info` field can contain any kind of data that the developer so chooses, and it is up to the developer to implement this, using an `IServerInfoProvider` implementation.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdcronqvist%2Farachne","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdcronqvist%2Farachne","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdcronqvist%2Farachne/lists"}