Luna Multiplayer: turning Kerbal Space Program into a shared simulation over UDP
Multiplayer mod for Kerbal Space Program (KSP)
At a glance
- What is it?
- Luna Multiplayer is a multiplayer mod for Kerbal Space Program that synchronises vessels between players over reliable UDP using the Lidgren library, with NTP time sync, interpolation for bad network conditions and NAT punchthrough so a server does not need ports opened on the router. It is MIT licensed, written in C#, and ships as a client, a server and a master server.
- Who is it for?
- Luna Multiplayer suits a group of Kerbal Space Program players who want to build and fly vessels together rather than separately, because the mod handles the parts that make a shared simulation tolerable: time synchronisation across clients, interpolation so a vessel does not jump on a bad connection, and NAT punchthrough so a host does not have to configure a router.
- Can I use it commercially?
- Yes. MIT 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 53 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 October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The hard part of multiplayer in a physics game is time, not bandwidth
Luna Multiplayer is a multiplayer mod for Kerbal Space Program, and the feature list in the README is a good map of what the project actually had to solve.
The first entry on the list is clean and optimized code, based on systems and windows which makes it easier to read and modify. The second is multi threaded. The third is NTP protocol to sync the time between clients and the server.
That third item is the one that tells you this is a physics simulation and not a standard game. Kerbal Space Program is a game where orbital mechanics is the gameplay, and every client running the same simulation needs to agree on what time it is. Without that agreement, a vessel's position diverges between clients within seconds and the shared session falls apart.
So the architecture is: reliable UDP for the transport, NTP for a shared clock, and interpolation on top so that when the network is not perfect the visible result is a slight lag rather than a teleport.
The interpolation entry is explicit about the purpose: so the vessels won't jump when there are bad network conditions. That is the correct trade for a networked vehicle simulation. You accept that the picture you see is a short extrapolation rather than the exact server state, and in exchange the vessel never appears to teleport across the map.
The transport choice is the Lidgren library, generation 3, used for reliable UDP message handling. UDP rather than TCP is the right call for this class of traffic, because game state is worthless once it is late, and TCP's retransmission and ordering guarantees turn a lost packet into a stall rather than a dropped update.
The primary language is C#, the licence is MIT with a LICENSE file at the repository root, the default branch is master, and the last push was on 2026-08-31 with the most recent release 0.29.2 from 2026-05-17 and a nightly build 0.30.0-Draft from 2026-06-02.
NAT punchthrough and IPv6 exist so a server does not need a router configured
Two features in the list deal with the reason most people cannot host a game server: the network behind the router.
The nat-punchthrough feature exists so a server doesn't need to open ports on it's router. That is the whole promise, and it is what separates LMP from the typical situation where you host a server on your home connection and either configure port forwarding or use a relay.
IPv6 support for client to server connections completes the picture, and the README states the reason directly: allowing connection setup even behind symmetric IPv4 NAT. A symmetric NAT is the hard case, because the NAT assigns a different external port for each destination, so the two peers cannot guess each other's address and a direct connection fails. IPv6 sidesteps the whole problem where it is available, and punchthrough handles the cases where it is not.
For the servers that do want to be reachable directly, there is UPnP support for servers and master servers. That is the automatic version of port forwarding: the server asks the router to open the port on its behalf.
So there are three mechanisms stacked, and they are not redundant. UPnP is the cooperative path where the router can be asked. NAT punchthrough is the cooperative path where the peers negotiate directly without router help. IPv6 is the path where the network architecture no longer creates the problem.
The list also mentions servers displayed within the mod, which is the discovery side, and it leads naturally to the master server concept. The master server is a directory of running servers, and the README links a status page for it, with separate entries for Release and Nightly versions.
The settings are saved as XML, which is worth noting for anyone who wants to script configuration, and the mod is multilanguage.
Two of the engineering entries are about avoiding pauses rather than about networking protocol. Every network message is cached in order to reduce the garbage collector spikes, and there is cached QuickLZ for fast compression without generating garbage. Both point at a project that has been profiled, because garbage collection pauses in a real-time simulation are visible to the player as a stutter.
The build is a Visual Studio solution with server, master server and updater projects
The repository is a Visual Studio solution, LunaMultiplayer.sln, with a DotSettings file, and the project layout tells you what the mod is made of.
LmpClient/ is the in-game client. Server/ is the dedicated server. LmpMasterServer/ and MasterServer/ are the two master server components, with MasterServersList/ holding the configured list and LmpMasterServerTest/ alongside. LmpUpdater/ is the automatic updater that the README links with a Latest build updater badge. LmpCommon/, LmpGlobal/, LmpCommonTest/ and ServerTest/ are the shared code and the test projects.
Then the third-party parts, which are unusually prominent for a mod repository. Lidgren/, Lidgren.Core/ and Lidgren.Net/ are three separate directories, and uhttpsharp/ is another vendored dependency. The Lidgren directories are the networking library the README names, and their presence at the top level rather than as a package reference means the networking code is part of the tree.
There is also an External/ directory, a Documentation/ directory, Scripts/, and an assets image called NetRuntime.png.
The build and release story is split across three CI systems, and the status table at the bottom of the README makes the split explicit. The master branch row carries an AppVeyor build badge, an AppVeyor tests badge, a last commit badge and a commit activity badge. There is also an appveyor.yml at the root with an appveyor_discord.ps1 script, and an azure-pipelines.yml alongside it.
Two release channels run in parallel, and the table of master servers separates them cleanly. Dagger, maintained by gavazquez, has a Release server at servers.lunamultiplayer.com on port 8701 and a Nightly server at port 8751. DasSkelett runs ms.lmp.dasskelett.dev and ms-nightly.lmp.dasskelett.dev, and Nightshade runs lmp.nightshade.fun with a nightly sub-path. Both channels are also documented separately in the wiki, with pages for how to get the latest version of LMP and how to get nightly builds.
So a player chooses whether to run a stable build or the nightly, and finds servers in the matching list.
Running a dedicated server in Docker needs four mounted directories
The docker-compose.yml in the repository is the most concrete piece of deployment information available, and it shows what the server needs at runtime.
version: '3.3'
services:
lunamultiplayer:
image: lunamultiplayer:local
build:
context: ./
dockerfile: Dockerfile_Server
container_name: lunamultiplayer
environment:
- TZ=CET
ports:
- '8800:8800/udp'The comments above the file carry the operating instructions: you also need the Dockerfile_Server file, put it in the same directory as this file, and you build and create the container with docker-compose up -d --build. You may set the version of the server when an update is released, see the args argument. You attach to the container with docker-compose exec lunamultiplayer /bin/ash.
The port mapping is 8800 to 8800 over UDP, which is consistent with the transport design. And the commented line for the website on port 8900 tells you there is an optional web interface that is off by default.
The volumes are the interesting part.
volumes:
- '/opt/LMPServer/Config:/LMPServer/Config'
- '/opt/LMPServer/Universe:/LMPServer/Universe'
- '/opt/LMPServer/Plugins:/LMPServer/Plugins'
- '/opt/LMPServer/logs:/LMPServer/logs'
restart: unless-stoppedFour directories are mounted out of the container: Config, Universe, Plugins and logs. The Universe is the game's shared solar system data, so it has to persist and be shared rather than regenerated. Plugins is there so a server operator can drop in extensions without rebuilding the image. Config is where the server's settings live, and logs are mounted so they survive a container restart.
The restart policy of unless-stopped is what keeps a server up across a host reboot.
Two files in the root support this: Dockerfile_Server and Dockerfile_MasterServer. The MasterServer/ directory is the master server itself, which is a separate component from the game server: the game server hosts a session, and the master server is the directory that lists it.
The contributing section asks for code that survives the author leaving
The contributing note in the README is unusual and worth reading in full, because it states the project's real risk in plain terms.
Please write the code as you were going to leave it, return after 1 year and you'd have to understand what you wrote. It's very important that the code is clean and documented so in case someone leaves, another programmer could take and maintain it. Bear in mind that nobody likes to take a project where it's code looks like a dumpster.
That is a project acknowledging its own bus factor and asking contributors to compensate for it. Whether the codebase actually meets that standard is a separate question, and the debug and build wiki pages are the place to find out, since the README points at pages for how to install, how to play with LMP, how to build LMP and how to debug LMP in Visual Studio.
There is also a test project, so contributions that add tests are welcome rather than merely tolerated. The solution has ServerTest/, LmpMasterServerTest/ and LmpCommonTest/ projects, which is a reasonable test surface for a project of this size.
Support for users is routed to the wiki. The Troubleshooting page in the wiki is meant to solve the most common issues with LMP, and the README asks people to visit it before reporting problems. Support for the project itself is a Discord server, and there is a KSP forum post linked from the README as the announcement thread.
There is a donation link, PayPal through paypal.me/gavazquez, and the README frames it in terms of what it buys: it will encourage us to do future releases, fix bugs and add new features.
The primary language is C#, the repository includes a .devcontainer/ directory and a .vsconfig file for editor and tool configuration, and the project is maintained under the LunaMultiplayer organisation with the homepage at lunamultiplayer.com.
Where Luna Multiplayer is the wrong tool
The first wrong-tool case is a group that wants to share a campaign rather than a session. The feature list says it supports career and science modes with funds, science and strategies shared between all players, and the same list has support for groups or companies inside career and science modes still unchecked. So what is shared is the economic and research state, and the finer-grained notion of a company or a group of players with their own vessels and their own progress is not implemented. A group that wants to run a shared career with separate player identities inside it will find the shared state is coarser than they expect.
The second case is a server operator who wants to expose a web interface out of the box. The compose file has the website port commented out, which means it is off by default and you have to enable it yourself, and the documentation does not describe what the web interface provides. The default deployment is a game server on UDP.
The third case is a player who wants the two release channels to be interchangeable. Release and Nightly are tracked separately on the master servers, with separate lists and separate server instances, so a group where one person is on a nightly build and another is on a release build will find that their sessions do not line up the way they expect.
The fourth case is a project that needs reliable delivery rather than low latency. Lidgren's reliable UDP handles message reliability over an unreliable transport, and the design optimises for fresh state over guaranteed ordered delivery, which is correct for game state and wrong for, say, transferring a file or a chat message that must not be lost. The mod is not a general-purpose networking library for a game with chat and file requirements of that kind.
One practical caution about the Docker path. The compose file mounts host directories under /opt/LMPServer, and the container is configured with the TZ environment variable set to CET, with no instruction in the compose file to change it. A server operator in another timezone will want to set that variable to match, since the log timestamps and any time-based server behaviour depend on it, and the Universe and Config directories have to exist on the host with the right ownership or the container will not be able to write to them.
On licence, MIT with a LICENSE file at the root and no copyleft obligation, so a server operator can modify the client or server and redistribute it. The more consequential terms are elsewhere: the mod runs inside Kerbal Space Program, so it inherits whatever terms the game itself carries, and the vendored Lidgren and uhttpsharp directories carry their own licences which a redistributor of a modified build would need to keep intact.
Editorial conclusion
Luna Multiplayer suits a group of Kerbal Space Program players who want to build and fly vessels together rather than separately, because the mod handles the parts that make a shared simulation tolerable: time synchronisation across clients, interpolation so a vessel does not jump on a bad connection, and NAT punchthrough so a host does not have to configure a router. It does not suit someone who wants the campaign progress of a single save shared, because career and science mode sharing covers funds, science and strategies rather than a merged campaign. Before adopting, check the status table for the master branch and pick a Release or Nightly build from the master server list to match, since the two are tracked separately.
Frequently asked questions
What is Luna Multiplayer?
Luna Multiplayer, or LMP, is a multiplayer mod for Kerbal Space Program. It synchronises vessels between players over reliable UDP using the Lidgren library, and adds NTP time synchronisation between clients and the server plus interpolation so vessels do not jump when network conditions are poor.
Does a Luna Multiplayer server need port forwarding?
Not necessarily. The mod includes a nat-punchthrough feature so a server does not need to open ports on its router, IPv6 support for client to server connections allowing setup even behind symmetric IPv4 NAT, and UPnP support for servers and master servers. The Docker compose file publishes the game port as 8800 to 8800 over UDP.
How do I run a Luna Multiplayer dedicated server with Docker?
Put the Dockerfile_Server file in the same directory as docker-compose.yml and run docker-compose up -d --build, then attach with docker-compose exec lunamultiplayer /bin/ash. The compose file mounts Config, Universe, Plugins and logs directories from /opt/LMPServer and sets the restart policy to unless-stopped.
What is shared between players in Luna Multiplayer career mode?
Funds, science and strategies are shared between all players, and the mod supports both career and science modes. Support for groups or companies inside career and science modes is listed as still to do in the README feature list.
How do I find a Luna Multiplayer server?
Servers are listed through master servers, and the README names Dagger, DasSkelett and Nightshade, each with separate Release and Nightly listings. The wiki links cover how many servers are up, how to get the latest version of LMP, and how to get nightly builds.
What license is Luna Multiplayer released under?
It is released under the MIT license, with the LICENSE file at the root of the repository. The primary language is C#, and the last push to the repository was on 2026-08-31.
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/lunamultiplayer-lunamultiplayer)Was this useful?