mas-bandwidth/netcode: a UDP connection layer for multiplayer games, in C
Secure client/server protocol for multiplayer games built on top of UDP
At a glance
- What is it?
- netcode is a C library that adds secure, connection-oriented sessions on top of UDP. It is aimed at teams that do their own matchmaking and want encrypted packets without writing handshake, token and slot logic from scratch.
- Who is it for?
- Adopt netcode if you are writing a game server in C or C++ and already plan to run matchmaking in a web backend that hands out connect tokens. Do not adopt it if you need reliable ordered delivery, RPCs or replication out of the box; that is yojimbo's layer, not this one.
- Can I use it commercially?
- Yes. BSD-3-Clause is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 17 days ago.
- What is it written in?
- Mainly C, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 24, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The gap netcode fills between raw UDP and a full game networking stack
UDP gives you datagrams and nothing else. There is no connection, so a server has no way to tell a returning player from a stranger, and no way to stop a stranger from sending packets that look like a player's. The README frames the choice plainly: real-time games use UDP because TCP's head of line blocking delays newer packets while it waits for older dropped ones to be resent, but UDP leaves connection management entirely to you.
netcode is the layer that fills that gap and stops there. It provides a connection-oriented protocol on top of UDP, with encrypted and signed packets, a fixed number of client slots, and clean disconnects. It deliberately does not provide reliable ordered messages, RPCs or state replication. The intended user is a team with an existing game server and a web backend that can perform matchmaking, who wants to get to the point of exchanging unreliable unordered packets and then build the rest of their protocol. If you want reliability and serialization included, the same author's yojimbo is the library that sits above this one.
Connect tokens, client slots and the server's clock
The mechanism has three parts. First, a private key. The server is created with a 32 byte private key, and the README is explicit that this key must never ship inside a client executable. Second, a connect token. The client asks your backend for one over a REST API, and the README points at an example in the yojimbo repository (matcher/main.go) for that server side flow. The client then calls netcode_client_connect with the token. Only clients your backend authorized can complete the handshake, which is what makes the matchmaking step meaningful.
Third, slots. netcode_server_start takes a slot count, and a connecting client is assigned a client index. If all slots are taken the connection is denied quickly rather than left hanging. Disconnects on either side free the slot immediately, with timeouts covering the case where a peer simply vanishes.
One configuration detail carries real weight. max_connect_token_lifetime is described as the longest lifetime in seconds your backend issues connect tokens with. The server refuses any token that could have been issued before it started, and that value is how it decides which those are. Set it lower than your backend's real token lifetime and legitimate clients get rejected; set it higher and the window the server is willing to accept widens. The README does not document rollback or key rotation, so plan for restart behaviour yourself.
Building netcode and creating your first server
The repository ships a CMakeLists.txt and a BUILDING.md, so the build path is CMake. The README itself does not print a cmake command line, so check BUILDING.md for the exact invocation rather than guessing flags. The library depends on libsodium for cryptography; the repository carries a sodium/ directory, and the README credits the sodium library for all cryptography.
The README's usage section starts from a key and a server config. This is the shape of the setup code, copied from the README with a test key that must not be used in production:
static uint8_t private_key[NETCODE_KEY_BYTES] = { 0x60, 0x6a, 0xbe, 0x6e, 0xc9, 0x19, 0x10, 0xea,
0x9a, 0x65, 0x62, 0xf6, 0x6f, 0x2b, 0x30, 0xe4,
0x43, 0x71, 0xd6, 0x2c, 0xd1, 0x99, 0x27, 0x26,
0x6b, 0x3c, 0x60, 0xf4, 0xb7, 0x15, 0xab, 0xa1 };With that key in hand, the README builds a server config, copies the key in, and sets the token lifetime. The address string is host:port, and 40000 is the port used in the README example:
char * server_address = "127.0.0.1:40000";
struct netcode_server_config_t server_config;
netcode_default_server_config( &server_config );
server_config.max_connect_token_lifetime = 30;
memcpy( &server_config.private_key, private_key, NETCODE_KEY_BYTES );
struct netcode_server_t * server = netcode_server_create( server_address, &server_config, time );Starting the server is one call, and the second argument is the number of client slots. The README uses 16:
netcode_server_start( server, 16 );On the client side the flow is: fetch a connect token from your backend, then hand it to the client. The README shows the single call, and nothing more:
netcode_client_connect( client, connect_token );After that the client has a client index and the two sides exchange encrypted, signed packets. For the full loop, the README directs readers to client.c and server.c in the repository root, and client_server.c is a combined example. Expect to read those files, because the README stops at the calls above.
What netcode does not give you, and when that is the wrong choice
The most common mismatch is expecting a complete multiplayer framework and getting a connection layer. netcode does not deliver reliable ordered messages, fragmentation and reassembly of large messages, RPCs, or state replication. If your game needs any of those, you build them on top, or you use yojimbo, which the README lists as another library by the same author alongside reliable and serialize. Teams that want a batteries-included engine networking solution should look at the Unity or Unreal integrations listed in the README instead of the C core.
A second constraint is the key model. The private key lives on the server and on the backend that mints tokens. Any deployment where the backend is operated by someone else, or where the key is baked into a build artifact, breaks the security story the README describes. The README warns about this in the strongest terms it uses anywhere: do not include your private key in your client executable.
A third is operational. The server refuses tokens that could have been issued before it started, which means a server restart interacts with your token lifetime. The README documents the configuration key but not what happens to in-flight clients across a restart, so that behaviour has to be established from the source.
How netcode compares with an engine networking stack
The nearest thing to a competitor in the same problem space is Unity's Netcode for GameObjects, which appears in the search data around this project. The difference in approach is structural. Netcode for GameObjects is a Unity package that manages networked objects, ownership and synchronization inside the engine's lifecycle; you add components and the framework handles replication. netcode is a C library with no engine dependency at all. It gives you a session, a slot and encrypted packets, and leaves object replication to you.
That makes the two hard to compare on features, because they solve different halves of the problem. If your server is a Unity process and you want objects to replicate, the engine package is the shorter path. If your server is a standalone C or C++ binary that talks to a web matchmaker, netcode fits without dragging an engine runtime along. The trade is that you write more of the protocol yourself.
The README also lists netcode implementations in C#, Go, Rust, TypeScript, Unity and UE4, and points at STANDARD.md and IMPLEMENTERS.md for anyone writing another. IMPLEMENTERS.md is described as findings other implementations should check themselves against, including a replay-protection overflow and some corrected errata, which is worth reading even if you only use the C version.
Licence, crediting and the cost of staying current
netcode is BSD 3-Clause. That is a permissive licence, and the README separates the legal terms from a request: if you use the library in a product, credit it as "netcode - Glenn Fiedler and Rowan Claude" in your product credits. The README states the licence does not require this and calls it an official request. Treat the crediting line as a courtesy you can honour cheaply, and read the LICENCE file for the actual terms rather than relying on this summary. Nothing here is legal advice.
The maintenance picture is concrete. The repository is not archived, and the last push was on 2026-09-13. Releases are frequent and small: v1.4.6 changed payload packets to carry the reader's eight bytes of slack, and v1.4.7 tightened setup by refusing missing override and loopback callbacks and hardened the simulator and address_to_string. Those are incremental changes, not a rewrite, which is what you want from a protocol library you have already integrated.
Upgrade cost is mostly the standard C integration cost: rebuild against the new netcode.c and netcode.h, then check whether your callbacks still satisfy the setup checks that v1.4.7 added. There is a SECURITY.md in the repository for reporting issues. The repository also carries fuzz/, tools/, profile.c and soak.c, which suggests the project treats packet parsing and load behaviour as things worth exercising directly.
Editorial conclusion
Adopt netcode if you are writing a game server in C or C++ and already plan to run matchmaking in a web backend that hands out connect tokens. Do not adopt it if you need reliable ordered delivery, RPCs or replication out of the box; that is yojimbo's layer, not this one. Before writing code, read STANDARD.md and IMPLEMENTERS.md and confirm your backend's connect token lifetime matches the max_connect_token_lifetime you configure on the server.
Frequently asked questions
What is netcode in gaming?
In this project's terms, netcode is a secure client/server protocol for multiplayer games built on top of UDP. It supplies the connection, encryption and slot management that UDP itself does not provide.
What is a netcode token?
The README calls it a connect token. Your client requests one from your backend over a REST API, and the client passes it to netcode_client_connect. Only clients your backend authorized can connect to the server.
How do I use netcode?
Generate a 32 byte private key and keep it off the client. Create a server with netcode_server_create using a netcode_server_config_t, start it with a slot count, and have clients connect with a connect token. The README points to client.c and server.c for the full example.
How do I install netcode?
The repository contains CMakeLists.txt and BUILDING.md, so the build uses CMake. The README does not list install commands, so follow BUILDING.md for the exact configure and build steps.
How do I access netcode?
Access is through the C API in netcode.h. You create a server with netcode_server_create, start it with netcode_server_start, and connect clients with netcode_client_connect once your backend has issued a connect token.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/mas-bandwidth-netcode)