
So here's the thing.
Most SCP: Secret Laboratory servers just run whatever Northwood provides out of the box and call it a day. Fair enough. But if you've ever watched one under load… yeah. It’s not exactly lightning.
MeowNet exists because of that frustration. It’s a completely custom server runtime written in C# on .NET 9, built from the ground up with one simple (maybe slightly obsessive) goal: make the server run faster, smoother, and cleaner than the official one. In basically every measurable way.
No patches. No band-aids. Just a fresh start.
Here’s the awkward truth people don’t like to say out loud: the stock SCP:SL server is still basically a Unity game running without graphics.
Headless, sure—but still Unity.
Which means the server drags along a surprising amount of baggage:
None of this is something you can realistically “fix” with plugins. Trust me, people have tried.
MeowNet just… sidesteps the whole mess.

One thing that confuses people at first: MeowNet isn’t running inside Unity at all.
It’s a standalone .NET 9 executable. Just a regular process.
Instead of embedding itself into the game like a mod or wrapper, it references the game's assemblies directly—things like Assembly-CSharp.dll, Mirror.dll, and UnityEngine.CoreModule.dll. Those are treated as external libraries, and only the parts that are actually useful get pulled in.
Everything else? Left behind with the engine.
This is probably the part people double‑take at.
MeowNet actually runs its own physics thread.
At startup, the server calls:
WorldExtensions.EnableGlobalPhysicsThread()
That spins up Unity’s physics engine in a dedicated background thread. Completely separate from networking, session handling, and all the usual server logic.
So collision checks, hitboxes, world interaction—those things are constantly being calculated independently instead of being jammed into an already overloaded game loop tick.
A lot of custom server projects skip physics entirely. Some just trust the client (which… yikes). Others fake it.
MeowNet runs it properly. Server-side. On its own thread. No shortcuts.
Another design decision: every subsystem lives inside its own BackgroundService.
Each one does exactly one job. Nothing more. Nothing weirdly intertwined.
They also start in a deliberate order and can shut down cleanly if needed—because servers crash enough without fighting their own architecture.
A few examples:
ListenersService — registers remote servers from config and runs a tight 10ms update loop across them so network state never gets staleSessionService — processes session logic through a ConcurrentQueue<Action> on its own dedicated thread, meaning session work can’t block networking even if it triedSchedulerService — a thread-aware task scheduler that actually knows which thread is which (by name), routing callbacks where they belongLoggingService — structured logging through MeowLogger, with labeled output across all servicesCommandsService — non-blocking console input using Console.KeyAvailable plus Task.Run, along with pooled StringBuilder usage so command parsing doesn’t spray allocations everywhereBasically: each system stays in its lane. Servers behave much better when they do.
Garbage collection pauses are one of the classic reasons servers hitch. You’ve probably seen it—everything freezes for a split second and then continues like nothing happened.
Not great.
So MeowNet tries very hard not to allocate memory on hot paths.
On top of that, the ReadWriterInitializer scans all loaded assemblies via reflection and automatically invokes any InitReadWriters methods it finds to then write them in files usable so dynamically creating them.
It’s actually similar to how Unity initializes some of its networking internals—just done inside a clean .NET runtime without dragging the entire engine along for the ride.
Result: fewer allocations, fewer GC pauses, and a server that stays stable even when things get busy.
Networking code loves magic numbers. Everyone hates them.
To avoid that headache, MeowNet includes a small code generation tool called NetworkingMessagesGenerator.
What it does is pretty straightforward:
It reflects over Mirror’s networking layer and SCP:SL’s assemblies, finds every NetworkMessage type and [Command] method, and generates a NetworkingMessages.cs file containing stable ushort constants for each message.
The command hashes are calculated using the same stable hashing algorithm the game uses internally, so everything lines up perfectly.
Which means instead of scattered integers like 34721 showing up in networking code, you get clear named constants tied directly to the game’s assemblies. Much easier to read. Much harder to screw up.
The core of MeowNet is already solid—threading, networking, pooling, physics, all that foundational stuff works and works well.
What’s still evolving is the gameplay layer sitting on top of it. Systems are being built gradually, one piece at a time.
But that’s kind of the point.
When the base is designed for performance from day one, every new system inherits those guarantees automatically instead of trying to bolt optimization onto something that was never meant to scale.
And honestly? That approach just feels better.