TL;DR: I got tired of every game needing custom netcode, so I built Project Neon — a minimal UDP protocol that works for any multiplayer game. 8-byte header, zero assumptions about your game logic, and you define your own packets. MIT licensed, works with Unity/Unreal/Godot via JNI.
The Problem Nobody Talks About
You want to add multiplayer to your game. Simple, right?
Option 1: Use a library (Photon, Mirror, Netcode for GameObjects)
- ✅ Fast to get started
- ❌ Vendor lock-in
- ❌ Black box you can't modify
- ❌ Doesn't work with your custom engine
Option 2: Roll your own
- ✅ Full control
- ❌ You're implementing TCP handshakes in 2026
- ❌ NAT traversal is still a nightmare
- ❌ You just reinvented the same connection management everyone else has
There's no middle ground. Either you get a bloated framework with RPCs and state sync you don't need, or you're writing raw socket code and debugging why packets disappear behind your router.
What If We Just... Didn't?
Here's the insight: Every multiplayer game needs connection management. Zero games need the same game logic.
So I built Project Neon with one rule: The protocol should know nothing about your game.
record NeonPacket(
PacketHeader header, // 8 bytes - that's it
PacketPayload payload // Your game, your rules
) {}
The header:
- Magic number (are you even talking Project Neon?)
- Version (protocol compatibility)
- Packet type (0x01-0x0F reserved, 0x10+ yours)
- Sequence number (for ordering/reliability)
- Client ID + Destination (who's talking, who's listening)
That's it. The relay doesn't parse your payloads. It doesn't care if you're sending player positions, chess moves, or Minecraft blocks. It just routes bytes.
Show Me Code
Client connects to a session:
NeonClient client = new NeonClient("PlayerName");
if (client.connect(12345, "relay.example.com:7777")) {
System.out.println("Connected! My ID: " + client.getClientId());
// Game loop
while (gameRunning) {
client.processPackets(); // Handle incoming
updateGame(); // Your logic
sendGameState(client); // Your packets
}
}
Define your own packet:
// You decide what this looks like
record PlayerMovement(
int playerId,
float x, float y, float z,
float velocityX, float velocityY, float velocityZ
) {
byte[] serialize() {
ByteBuffer buf = ByteBuffer.allocate(28);
buf.putInt(playerId);
buf.putFloat(x).putFloat(y).putFloat(z);
buf.putFloat(velocityX).putFloat(velocityY).putFloat(velocityZ);
return buf.array();
}
}
// Send it
client.sendGamePacket((byte) 0x10, 0, movement.serialize()); // 0 = broadcast
That's the entire API. No inheritance, no component system, no "NetworkBehaviour" base class. Just packets.
The Architecture (It's Actually Simple)
┌────────┐ ┌───────┐ ┌────────┐
│ Client │ ─────→ │ Relay │ ─────→ │ Host │
└────────┘ └───────┘ └────────┘
│
↓
(broadcasts to others)
Why a relay? NAT traversal. Your game works behind routers without port forwarding. The relay is dumb and fast — it validates the 8-byte header and forwards raw bytes.
Client-Server or Peer-to-Peer? Yes. The "host" is just another client with special privileges. You decide if it's authoritative or if clients trust each other.
Real Talk: What This Doesn't Do
Project Neon is not a game networking framework. It's infrastructure.
You still need to implement:
- ❌ Player synchronization (positions, animations)
- ❌ Client-side prediction / server reconciliation
- ❌ Lag compensation
- ❌ Authentication (there's no passwords — you add that)
What you get:
- ✅ Connection management (connect, disconnect, reconnect)
- ✅ Session handling (relay routes everything)
- ✅ Packet ordering (sequence numbers in header)
- ✅ Optional reliability (ACK/retry utility for critical packets)
- ✅ Rate limiting (relay blocks floods)
- ✅ Metrics (latency tracking, packet counts)
Think of it like Express.js for game networking. It handles the boring parts (sockets, routing, lifecycle) so you can focus on your game.
Cross-Engine? Yeah.
Java core with JNI bindings for C/C++. Works with:
- Unity (call via JNI or run Java directly)
- Unreal Engine (link
libneon_jni.soas ThirdParty) - Godot (GDNative/GDExtension)
- Custom C++ engines
- Literally anything that can call C functions
// C API example
NeonClientHandle* client = neon_client_new("PlayerName");
neon_client_connect(client, 12345, "127.0.0.1:7777");
while (game_running) {
neon_client_process_packets(client);
// your game loop
}
neon_client_free(client);
Security: Let's Be Honest
Project Neon has no encryption. It's plaintext UDP.
Why? Because encryption adds latency, and for LAN parties or trusted networks, you don't need it. For internet deployment, you should:
- Run the relay behind a VPN/firewall
- Implement app-layer encryption (AES-GCM) for sensitive data
- Add authentication in your game code (use the
gameIdentifierfield)
There's a 3000-word SECURITY.md that breaks down every threat and mitigation. Read it before deploying to the internet.
UDP is also unreliable (packets get lost). You can:
- Use the built-in
ReliablePacketManagerfor critical events - Send redundantly (position updates every frame don't need ACKs)
- Implement your own ACK logic with sequence numbers
Performance
Latency budget:
- Network RTT: 20-50ms (LAN) / 50-200ms (internet)
- Relay forwarding: <1ms
- Packet serialization: <0.1ms
- Total added overhead: ~1ms
Throughput:
Example with 32 clients, 30 packets/sec, 200 bytes/packet:
- Per-client: 6 KB/s
- Relay total: ~6 MB/s (with broadcast)
The relay is single-threaded and handles 1000+ packets/sec easily. For higher loads, run multiple relays with session-based load balancing.
Getting Started
# Clone and build
git clone https://github.com/Quiet-Terminal-interactive/ProjectNeon
cd ProjectNeon
mvn clean package
# Run relay
java -jar target/neon-relay.jar
# Run example host (new terminal)
java -jar target/neon-host.jar 12345
# Run example client (new terminal)
java -jar target/neon-client.jar
Maven integration:
<dependency>
<groupId>com.quietterminal</groupId>
<artifactId>project-neon</artifactId>
<version>1.1.0</version>
</dependency>
Full docs: github.com/Quiet-Terminal-interactive/ProjectNeon
What's Next
This is v1.1.0 (Beta). The roadmap includes:
- [ ] Session persistence (survive relay restarts)
- [ ] DTLS support (optional encryption)
- [ ] NAT traversal (STUN/TURN integration)
- [ ] WebSocket relay variant (browser games)
- [ ] Prometheus metrics endpoint
But the core is stable. I've been using it for a Minecraft multiplayer plugin and it just works.
Why I Built This
I got tired of seeing the same connection logic rewritten in every game. TCP handshakes, UDP reliability layers, session management — it's solved problems, yet every engine makes you start from scratch.
Project Neon is my answer: Minimal infrastructure so you can build games, not protocols.
If you're building a multiplayer game and don't want vendor lock-in or to reinvent sockets, give it a shot. It's MIT licensed, well-documented, and designed to get out of your way.
GitHub: https://github.com/Quiet-Terminal-interactive/ProjectNeon
Docs: README | Architecture | Security
Questions? Open an issue or email kohanmathersmcgonnell@gmail.com
Top comments (0)