MafiaNet is an actively maintained networking library built for game developers who need reliable, high-performance multiplayer networking. Built on the foundation of RakNet and SLikeNet, MafiaNet delivers battle-tested networking capabilities with modern C++ standards and security practices.
Supported Platforms: Windows, Linux, macOS (primary) | iOS, Android (limited)
- CMake 3.21+
- C++17 compatible compiler
- OpenSSL 1.0.0+
- Internet connection (first build fetches dependencies automatically)
Linux / macOS:
git clone https://github.com/MafiaHub/MafiaNet.git
cd MafiaNet
mkdir build && cd build
cmake ..
cmake --build . -j$(nproc) # Linux
cmake --build . -j$(sysctl -n hw.ncpu) # macOSWindows (Visual Studio):
git clone https://github.com/MafiaHub/MafiaNet.git
cd MafiaNet
# Generate Visual Studio 2022 solution
cmake -G "Visual Studio 17 2022" -A x64 -B build
# Build from command line, or open build/MafiaNet.sln in Visual Studio
cmake --build build --config Release| Option | Default | Description |
|---|---|---|
MAFIANET_BUILD_SHARED |
ON | Build shared library (.dll/.so/.dylib) |
MAFIANET_BUILD_STATIC |
ON | Build static library (.lib/.a) |
MAFIANET_BUILD_SAMPLES |
OFF | Build 80 sample applications and extensions |
MAFIANET_BUILD_TESTS |
OFF | Build test suite |
To build with samples:
cmake -DMAFIANET_BUILD_SAMPLES=ON ..#include "mafianet/peerinterface.h"
#include "mafianet/MessageIdentifiers.h"
// Create a peer
MafiaNet::RakPeerInterface* peer = MafiaNet::RakPeerInterface::GetInstance();
// Start as server
MafiaNet::SocketDescriptor sd(60000, 0);
peer->Startup(32, &sd, 1);
peer->SetMaximumIncomingConnections(32);
// Or connect as client
peer->Connect("127.0.0.1", 60000, nullptr, 0);
// Process incoming packets
MafiaNet::Packet* packet;
while ((packet = peer->Receive()) != nullptr) {
switch (packet->data[0]) {
case ID_NEW_INCOMING_CONNECTION:
printf("Client connected\n");
break;
case ID_CONNECTION_REQUEST_ACCEPTED:
printf("Connected to server\n");
break;
}
peer->DeallocatePacket(packet);
}
// Cleanup
MafiaNet::RakPeerInterface::DestroyInstance(peer);
|
|
|
|
MafiaNet provides a modular plugin system for extending functionality:
| Plugin | Description |
|---|---|
| ReplicaManager3 | Automatic object replication and state synchronization |
| RPC4 | Remote procedure calls with parameter serialization |
| FullyConnectedMesh2 | P2P mesh networking with host migration |
| NatPunchthrough | NAT traversal for peer-to-peer connections |
| FileListTransfer | Reliable file transfer with progress callbacks |
| DirectoryDeltaTransfer | Incremental directory synchronization |
| Autopatcher | Delta patching system for game updates |
| RakVoice | Voice chat with Opus codec and noise suppression |
| ReadyEvent | Player ready state synchronization |
| TeamManager | Team assignment and balancing |
| Router2 | Message routing through intermediate peers |
| MessageFilter | Security filtering for incoming messages |
| PacketLogger | Network traffic logging and debugging |
| TwoWayAuthentication | Mutual authentication between peers |
| CloudComputing | Distributed data storage and retrieval |
| Lobby2 | Matchmaking and lobby system |
See the Plugin Documentation for detailed usage.
Full documentation is available at mafianet.mafiahub.dev
Documentation includes:
# Install dependencies
brew install doxygen # macOS
sudo apt install doxygen # Ubuntu/Debian
pip install -r docs/requirements.txt
# Build and serve
cd docs
./build.sh serve # http://localhost:8000MafiaNet/
├── Source/
│ ├── include/mafianet/ # Public API headers (include as "mafianet/...")
│ └── src/ # Implementation files
├── Samples/ # 80 example applications
│ ├── ChatExample/ # Simple chat application
│ ├── Ping/ # Basic UDP communication
│ ├── ReplicaManager3/ # Object replication demo
│ ├── NATCompleteClient/ # NAT traversal client
│ ├── NATCompleteServer/ # NAT traversal server
│ ├── RakVoice/ # Voice chat examples
│ ├── FileListTransfer/ # File transfer demo
│ └── Tests/ # Comprehensive test suite
├── DependentExtensions/ # Optional integrations
│ ├── Autopatcher/ # Delta patching system
│ ├── Lobby2/ # Matchmaking and lobbies
│ ├── RakVoice.cpp/h # Voice communication
│ ├── MySQLInterface/ # MySQL connectivity
│ ├── PostgreSQLInterface/# PostgreSQL connectivity
│ ├── SQLite3Plugin/ # SQLite integration
│ └── RPC3/ # Legacy RPC system
├── docs/ # Sphinx documentation source
└── cmake/ # CMake modules and helpers
MafiaNet automatically fetches required dependencies via CMake FetchContent:
| Dependency | Version | Used For |
|---|---|---|
| OpenSSL | 1.0.0+ | Encryption (required, system-installed) |
| bzip2 | - | Compression (Autopatcher) |
| miniupnpc | - | UPnP port forwarding |
| Opus | 1.5.2 | Voice codec (RakVoice) |
| RNNoise | - | Noise suppression (RakVoice) |
All tests are GoogleTest, built with MAFIANET_BUILD_TESTS=ON and run through CTest. Two suites live under Tests/:
- Unit tests (
Tests/Unit/, labelunit): deterministic and hermetic — no loopback networking, no timing. - Integration tests (
Tests/Integration/, labelintegration): real UDP over loopback. Each test runs in its own process, serially, with a timeout.
cmake -DMAFIANET_BUILD_TESTS=ON ..
cmake --build .
# Run everything
ctest --output-on-failure
# Only the fast, hermetic unit suite
ctest -L unit
# Only the loopback integration suite
ctest -L integrationTo debug a single test, run the binary directly with a filter:
./Tests/IntegrationTests --gtest_filter='DispatcherLive.*' --gtest_repeat=100 --gtest_break_on_failure- Range-based receive
Peer::incoming(): drains the receive queue with a range-for; each iteration yields a freshPacketPtrfreed at end of scope, andpkt.id()returns theID_TIMESTAMP-aware identifier - Startup builders
Peer::server()/Peer::client(): fluent chain foldingSocketDescriptor+Startup+ result check +SetMaximumIncomingConnections/Connectinto one call;start()returns a move-onlyResult<Peer>whose error preserves the underlyingStartupResult/ConnectionAttemptResult(tagged byPeerStage) instead of collapsing to a bool. Security stays opt-in (secure()/public_key()) - Serialization archives (
mafianet/Archive.h): oneserialize(Ar&)member template describes a type's wire format for both directions;WriteArchive/ReadArchiveadapt aBitStream, recursing into nestedserialize()types and falling through tooperator<</operator>>(incl. per-type specializations) for everything else - Typed message dispatcher (
mafianet/Dispatcher.h):on<T>(handler)auto-assigns ids fromID_USER_PACKET_ENUMin registration order (documented wire contract;on<T>(id, handler)pins explicit ids),on(id, handler)covers system messages,dispatch()skipsID_TIMESTAMPprefixes and hands handlers a deserializedTplus aSender(guid()/peer_guid()/address()/guid_string());encode()is the symmetric write path. Opt-in — the rawswitchstays fully usable - Typed
Peer::send/Peer::broadcast: serialize-and-send a registered message in one call via the dispatcher registry, with overridable defaults (Priority::High,Reliability::ReliableOrdered, channel 0); destination acceptsSystemAddressorRakNetGUID; rawSend()untouched - RakVoice built into the core library: header now
mafianet/RakVoice.h; Opus and RNNoise are fetched and linked into the core automatically — no separate extension build - Full GoogleTest migration: all 29 legacy tests ported, the
Samples/TestsTestInterfaceharness deleted; hermeticUnitTests+ loopbackIntegrationTestsunderTests/, one process per test via CTest,MAFIANET_BUILD_TESTSbuilds everything test-related (requiresMAFIANET_BUILD_STATIC); CI runs ctest with JUnit artifacts on all platforms
- Umbrella header
mafianet/mafianet.h: aggregates the core public headers (RakPeerInterface, types, message IDs,PacketPriority,BitStream,GetTime,Statistics) so the common path only needs#include "mafianet/mafianet.h". Additive — granular headers remain; encryption headers are intentionally omitted (security stays opt-in viaInitializeSecurity()) - Canonical type aliases (
mafianet/aliases.h):PeerInterface(RakPeerInterface),Guid(RakNetGUID),Statistics(RakNetStatistics),UnassignedGuid.usingaliases denoting the same types, so old and new names interoperate; legacy names left untouched - RAII handles
Peer&PacketPtr(mafianet/PeerHandle.h): own aRakPeerInterface/ receivedPacketand clean up on scope exit, removing manualDestroyInstance/DeallocatePacketbookkeeping. ChatExample client rewritten to use them - Thread-safe GUID value accessors (
mafianet/guid_util.h):MafiaNet::to_string(const RakNetGUID&)owns its buffer;connected_address(...)returnsstd::optional<SystemAddress>(sentinel →nullopt) PointGridSectorizer: uniform point grid with O(1)RemoveEntry/MoveEntryvia per-entry hash + swap-remove (early-out on same-cell moves), upsert add/move semantics, duplicate-freeGetEntries, and edge-cell clamping.GridSectorizerleft untouched- Breaking — scoped enum classes: the global
PacketPriority/PacketReliabilityC enums are removed in favour of scopedMafiaNet::Priority/MafiaNet::Reliability. Enumerator order (and the wire field) is preserved, but call sites must update (HIGH_PRIORITY→MafiaNet::Priority::High,RELIABLE_ORDERED→MafiaNet::Reliability::ReliableOrdered);NUMBER_OF_*sentinels are nowconstexprcounts inMafiaNet - Breaking — removed non-thread-safe
RakNetGUID::ToString(void)(shared static buffer); useMafiaNet::to_string(g).c_str() - Bug fix:
PeerHandleno longer dereferences a moved-fromPeerinreceive()
- Strong-typed
PeerGuid: a newenum class PeerGuid : uint64_tnames a peer'sRakNetGUIDvalue distinctly fromNetworkID(an object id), so the two can no longer be passed interchangeably in auint64_t-typed signature — removing a class of silent "passed the wrong id" bugs in ReplicaManager3 glue andvoid(uint64_t)callbacks. Convert withToPeerGuid()/ToGuid()and compare againstUNASSIGNED_PEER_GUID. As a trivially-copyable 8-byte scoped enum it serializes byte-identically throughBitStream(and thereforeVariableDeltaSerializer) to the rawuint64_tit replaces — fully wire-compatible, no netcode bump. Purely additive, no behavioural change
- Optional disconnect reason:
CloseConnectiongains a final optionalconst BitStream *reasonDataargument whose bytes are appended right after theID_DISCONNECTION_NOTIFICATIONmessage ID, so the remote peer can learn why it was dropped (e.g. a kick/ban enum plus a custom string). The receiver reads it like any other body —packet->data + 1forpacket->length - 1bytes. Only graceful disconnects carry a reason; locally-synthesized notifications (ID_CONNECTION_LOST, timeout/dead-connection) stay payload-less, so always tolerate a zero-length body. Wire-backward-compatible: peers that only inspectdata[0]are unaffected - Bug fix:
RakPeer::CloseConnectionno longer coerces an unresolved target index (-1) to0and readsremoteSystemList[0]— which targeted an unrelated peer's slot or crashed on an unallocated list; the close socket is now resolved without assuming a valid slot index
- Virtual worlds (dimensions): new per-entity / per-observer
VirtualWorldIdscoping on top of ReplicaManager3 — the SA-MPSetPlayerVirtualWorld/ routing-bucket model for instanced interiors (e.g. apartments). Players only see entities sharing their virtual world (orVIRTUAL_WORLD_GLOBAL), switchable at runtime with no reconnect. Derive entities fromVirtualWorldReplica3;Connection_RM3getsGet/SetVirtualWorld;ReplicaManager3getsGetConnectionsInVirtualWorld/GetGuidsInVirtualWorldandSetPlayerVirtualWorld. The filter is authority-only, so a downloaded copy never despawns the entity at its owner. SeeSamples/VirtualWorld
- ReplicaManager3:
GetReplicaAtIndexis nowconst, matching the other read accessors (GetReplicaCount,GetConnectionCount,GetConnectionAtIndex) — const methods iterating replicas no longer need aconst_cast. The returnedReplica3*stays non-const. Source-compatible (no break for existing non-const call sites)
- RPC4 user context:
RegisterFunction,RegisterSlot,RegisterBlockingFunctionand theRPC4GlobalRegistrationhandler constructors now take an opaquevoid *contextpassed back to the handler on every call — no more file-static global pointers to route an RPC to an object instance (each registration carries its own context) - Bug fix:
RakPeer::CloseConnectionno longer dereferences a nullrakNetSocketduring teardown (a pre-existing crash in release builds); falls back to the primary socket - Testing: added
RPC4ContextTest(slot/nonblocking/blocking context); quarantined the flakyManyClientsOneServerDeallocateBlockingTestin CI pending a teardown-race fix - Breaking: RPC4 handler signatures gained a trailing
void *contextand the registration calls take a context argument; there are no compatibility overloads (passnullptrwhen unused)
- Plugins: Added
DirectoryDeltaTransfer::AddFile(filePath, fileName)to queue a single file for upload (complements the recursiveAddUploadsFromSubdirectory)
- Namespace cleanup: Standardized on the
MafiaNetnamespace; removed the legacySLNetmacro in favor of anMNetshorthand alias, and dropped staleRakNetalias references - Single header set: Collapsed the legacy redirect-stub header layers into the canonical
mafianet/...includes - BitStream safety: Catch-all serialization now
static_asserts on trivially-copyable types (preventingstd::stringdouble-frees), with added length-prefixedstd::stringspecializations - Breaking: legacy include spellings and the
SLNetnamespace macro are removed; serializing non-trivially-copyable types via the genericBitStream::Write/Readis now a compile error
- Cross-platform: Full macOS and Linux support, merged
Socket2definitions, removed deprecated platform back-ends - Fixed IPv6 connectivity and initialization issues
- Upgraded dependencies: OpenSSL 3.6.0, miniupnpc 2.3.3, Opus 1.6.1; dependencies now fetched on demand via CMake
- Fixed undefined behaviour in congestion control and a null-socket crash in connection teardown
- CI now runs the full test suite on Linux, macOS and Windows, with numerous test-stability fixes
- RakVoice: Migrated from Speex to Opus codec with RNNoise noise suppression
- Added support for 8000, 16000, 24000, 48000 Hz sample rates
- Voice activity detection using Opus DTX
- Rebranded from SLikeNet to MafiaNet
- Updated to C++17 standard
- Modernized CMake build system
- Added Sphinx documentation with Breathe integration
- Removed pre-generated Visual Studio solution files
See CHANGELOG for full history.
MafiaNet continues the legacy of two foundational networking libraries:
- RakNet (2001-2014) - Industry-standard game networking library by Jenkins Software, used in countless multiplayer games. Acquired and open-sourced by Oculus VR.
- SLikeNet (2016-2019) - Community continuation by SLikeSoft that modernized RakNet with bug fixes, security patches, and C++11 support.
With SLikeNet no longer maintained, MafiaNet carries the torch forward—providing an actively developed, modern networking solution for the game development community.
- Discord: Join our server for support and discussion
- Documentation: mafianet.mafiahub.dev
- Issues: Report bugs or request features
- Contributions: Pull requests are welcome!
MafiaNet is released under the MIT License.