GameNetworkingSockets moves your packets and leaves your payload alone
Reliable & unreliable messages over UDP. Robust message fragmentation & reassembly. P2P networking / NAT traversal. Encryption.
At a glance
- What is it?
- Valve's C++ transport layer gives games a TCP-shaped connection carrying UDP-shaped messages, with lane scheduling, per-packet AES-GCM-256 and WebRTC ICE for peer to peer. The payload itself is explicitly not its job, and the naming inherits from an SDK you cannot fully have off Steam.
- Who is it for?
- Adopt GameNetworkingSockets when you need lane scheduling, per-packet encryption and ICE-based NAT traversal inside one library, and you can live with packing your own payload bytes. Do not adopt it for entity serialization, delta encoding or compression, and do not plan around the Steam Datagram Relay unless you are on Steam.
- 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 42 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 November 13, 2026, and from our analysis. They are not legal advice.
Star history
- ValveSoftware/GameNetworkingSockets10,065 ★ · +140
| Repository | 2026-09-22 | 2026-11-13 |
|---|---|---|
| ValveSoftware/GameNetworkingSockets | 9.9k | 10.1k |
140 Stars in the last 52 days, measured from the daily GitHub snapshot. Compare with other projects
Editorial analysis
Message-oriented semantics over UDP, with reliability chosen per message
The central design decision here is that a connection behaves like TCP while each message behaves like UDP. You open a connection, you accept one, and messages are discrete objects rather than a byte stream you have to frame yourself. Reliable and unreliable message types both run over the same connection, which puts the reliability decision at the call site instead of in the socket configuration. A position update and a chat line can share one connection and take different paths through it.
Above the MTU the protocol takes over. Messages larger than the underlying MTU are fragmented, reassembled and, when reliable, retransmitted, and the caller never sees the fragments. That removes the reassembly half of a reliable UDP protocol from your own code.
What it does not remove is everything about the payload itself, which is the subject of its own section further down. Keep that split in mind while reading the rest: the transport is opinionated about delivery and completely silent about meaning.
The ack vector lives in a wire format document, not only in the source
The reliability layer is specified in `src/steamnetworkingsockets/clientlib/SNP_WIRE_FORMAT.md`, and it is deliberately not a TCP-style sliding window. The model comes from the ack vector in DCCP, RFC 4340 section 11.4, and from Google QUIC, and Glenn Fiedler has written about it in the context of games.
The mechanism inverts who holds state. Instead of the receiver sending cumulative acks for a range, the receiver tells the sender the status of every packet number, whether or not a packet arrived with that number. The sender remembers which segments went into each packet it emitted, so it can deduce which segments need retransmitting rather than resending a whole window.
One consequence follows for anyone tuning a lossy link: the sender remembers which segments went into each packet it sent.
ConfigureConnectionLanes decides which stream waits for which
Multiple message streams on one connection are called lanes, and `ISteamNetworkingSockets::ConfigureConnectionLanes` is where you set their scheduling. A lane can take a strict priority value, a softer weight value drawn from weighted fair queueing, or a combination of the two, and head-of-line blocking becomes something you configure rather than something you discover in production.
This is where the library earns its keep in a real game loop. Chat, state replication and voice arriving on a single UDP connection will interfere unless something arbitrates between them. Here you decide whether chat waits behind a replication burst or takes a fixed share.
The cost is configuration surface. Lane setup is a per-connection decision with priorities and weights that only make sense against the bandwidth a session actually has. That tuning is yours to do.
AES-GCM-256 per packet, with QUIC's key derivation
Every packet gets AES-GCM-256, key exchange uses Curve25519 with cert signatures, and the shared key derivation and the per-packet IV are based on the design QUIC uses, with the underlying design document linked from the project page rather than paraphrased at length.
Note that the authentication service, the signaling service and the SDR relay service are all named as features available only on Steam, and the Steamworks SDK documentation is offered as the place for those APIs.
One boundary is worth stating on its own. Because the Steam Datagram Relay is a live service and Valve needs to control its security and backward-compatibility burden, the project states that it cannot offer SDR access on other platforms to all partners. Any architecture that leans on SDR is leaning on a capability that is not uniformly available off Steam, which makes it a deployment decision rather than a networking one.
No entity serialization, no delta encoding, no compression
The project keeps a short list of what it does not do, and it is worth reading as a boundary on bandwidth and CPU rather than as a gap in the feature set. Higher level serialization of entities and delta encoding of changed state variables are absent. So is compression.
Concretely, every byte you send on a lane is a byte you packed yourself. Replication code written on the assumption that the transport will delta-encode your changed fields will ship full state on every tick, and that traffic is exactly what the fragmentation and retransmission machinery then has to carry. If your protocol depends on bandwidth-sensitive compression, you add a codec in your own layer and you inherit its failure modes, including what happens to a partially decodable packet.
The fragmentation guarantee does not soften this. The library will fragment and reassemble messages larger than the underlying MTU, so an accidentally enormous payload turns into a bandwidth problem instead of the error a type or a length check would have caught.
NAT traversal borrows WebRTC's ICE, and the signaling server is yours
NAT traversal is delegated to Google WebRTC's ICE implementation rather than written from scratch, and there is a mode the project calls symmetric connect. Signaling is pluggable: you bring your own service, or you use Steam's, which is one of the features marked as Steam-only.
`ISteamNetworkingMessages` exists to solve one specific migration problem. It is an interface for UDP-based code, meaning non-connection-oriented code where every send names the recipient's address, so that existing code can be pointed at a peer to peer use case without being rewritten as connection-oriented. `README_P2P.md` carries the longer explanation, and `tests/test_p2p.cpp` shows two hosts connecting this way and doubles as a worked example of writing a signaling service plugin.
The consequence for a team off Steam is that you own the rendezvous infrastructure. The library supplies ICE and a message interface; someone still has to run the signaling service, keep it reachable and decide what a client does when it disappears.
The Steam names are a mirror of an SDK you cannot fully have
The names will make you wonder whether this pulls in Steam. It does not, and the project says so directly. The naming exists because this code is a subset of the Steamworks SDK API that carries the same name, published openly so that developers can write against that interface without hesitation, and the stated reason is to keep that API shape in front of people.
The split lands at link time. On Steam you link the Steamworks version and reach the additional services, including the Steam Datagram Relay network. Elsewhere you get this opensource version under a permissive BSD-3-Clause licence, and the project explicitly says to use it if you are not a Steam partner or have no game on Steam.
That inheritance has a running cost at review time. The code is kept in sync with Valve's internal Steam code, which is offered as the explanation for a dated coding style and an odd directory layout: folders named `tier0`, `tier1`, `vstdlib` and `common` carry abstraction layers that look unnecessary because they exist to support the larger internal tree. Reading this repository means reading extracted code, not code written for you.
CMake presets and vcpkg, with no binary and no install command
Building is pointed at `BUILDING.md`, with `BUILDING_WINDOWS_MANUAL.md` held separately for Windows, and the repository carries `CMakeLists.txt`, `CMakePresets.json`, a `vcpkg.json` and a `vcpkg_ports/` directory. The README points to BUILDING.md for build instructions, so an evaluator clones and builds. Continuous integration runs six workflows named for Ubuntu, Windows, macOS, iOS, soak and Linux flavors.
Two starting points are named concretely. `examples/example_chat.cpp` is a client and server pair using all reliable messages over ordinary IPv4, and `tests/test_p2p.cpp` gets two hosts connected peer to peer. `examples/trivial_signaling_server.py` with `trivial_signaling_client.cpp` covers the same signaling job, and `examples/vcpkg_example_chat/` shows the vcpkg path.
Beyond C++ the library exposes a plain C interface for binding to other languages, and third-party bindings exist for C#, Go and Rust. Those live in separate repositories with their own maintainers, so a binding's release cadence is not the C++ one below.
The last push to master was on 2026-10-03 and the repository is not archived. Recent tags are v1.6.1 on 2026-10-03, v1.6.0 on 2026-06-03 and v1.5.1 on 2026-05-04. One restriction deserves more attention than it usually gets: the project says this library has shipped on consoles, mobile platforms and non-Steam stores, and that you must contact Valve for access to that code because they are not permitted to distribute it here. Platform support named in the documentation is therefore not the same thing as code you can build from the public tree.
Editorial conclusion
Adopt GameNetworkingSockets when you need lane scheduling, per-packet encryption and ICE-based NAT traversal inside one library, and you can live with packing your own payload bytes. Do not adopt it for entity serialization, delta encoding or compression, and do not plan around the Steam Datagram Relay unless you are on Steam. Before writing code, read SNP_WIRE_FORMAT.md and check whether the lanes you would configure match the streams your game actually sends.
Frequently asked questions
Should I enable Steam networking?
Only if you ship on Steam and want what comes with it. The project names Steam's authentication service, signaling service and SDR relay service as features available only on Steam, and states that SDR cannot be offered on other platforms to all partners. Otherwise the opensource version is a subset of the same API under a BSD-3-Clause licence.
Should I use TCP or UDP for gaming?
This library is UDP with TCP-shaped ergonomics. The connection is connection-oriented like TCP, each message is discrete like UDP, and reliable or unreliable is chosen per message. Messages above the MTU are fragmented, reassembled and retransmitted by the protocol rather than by you.
Does GameNetworkingSockets serialize entities or compress my data?
No, and the project lists both as things it does not do, together with delta encoding of changed state variables. You pack every payload byte yourself, on a lane you configure through ISteamNetworkingSockets::ConfigureConnectionLanes.
What is ISteamNetworkingMessages for?
It is an interface designed to make it easy to port UDP-based code to peer to peer use cases, where UDP-based means non-connection-oriented code that names the recipient's address on every send. README_P2P.md holds the longer explanation and tests/test_p2p.cpp demonstrates the flow.
How do I build GameNetworkingSockets?
Build instructions live in BUILDING.md, with BUILDING_WINDOWS_MANUAL.md for Windows, and the repository carries CMakeLists.txt, CMakePresets.json, vcpkg.json and a vcpkg_ports/ directory.
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/valvesoftware-gamenetworkingsockets)Star history chart for your README
[](https://hysenlabs.com/projects/valvesoftware-gamenetworkingsockets)Was this useful?