Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
SimpleLobby
Host-side lobby tools split out of SimpleSell: whitelist, bans, lobby guard, RPC firewall, late join, /lobby, and a scrap guard against client mods that post interior scrap counts. Written by Claude & Chonk.
By Chonkzilla
| Date uploaded | 2 weeks ago |
| Version | 0.1.3 |
| Download link | Chonkzilla-SimpleLobby-0.1.3.zip |
| Downloads | 18 |
| Dependency string | Chonkzilla-SimpleLobby-0.1.3 |
This mod requires the following mods to function
BepInEx-BepInExPack
BepInEx pack for Mono Unity games. Preconfigured and ready to use.
Preferred version: 5.4.2100README
SimpleLobby
Written by Claude & Chonk
Your Lethal Company v81 lobby: whitelist, bans, the lobby guard, a host-side firewall against forged game
requests, late join, the crew list fix, /lobby, and a scrap guard against client mods that report the
interior's scrap to the lobby.
Host only. Only the host needs it. Everyone else can join with no mods at all, and vanilla players never notice it. A whitelisted friend who also has it gets a couple of extras (below).
New in 0.1.0: split out of SimpleSell. All of this used to be part of SimpleSell (up to 0.1.39). It is the same code with the same settings; SimpleSell 0.1.40 is selling, buying and organizing only. Your settings come across by themselves (see Coming from SimpleSell).
Commands
| Command | What it does |
|---|---|
/players |
Lists players, flagging anyone running networked mods |
/kick <name> |
Kicks a player |
/guard warn|kick |
Whether flagged players get a warning or an automatic kick |
/guard scrap on|off|log|warn|kick |
The scrap guard (below) |
/ban <name or steam id> |
Bans permanently by Steam ID, so a name change doesn't get around it. A name works even after they leave (from the join log), and a numeric profile link works too |
/unban <name or steam id> |
Lifts a ban |
/bans |
Lists bans |
/whitelist add|remove <name> |
Lets a trusted friend run some commands too (see below) |
/lobby status |
Tag, visibility, and what Steam reports about whether someone can join |
/lobby public|friends|private |
Changes who can find the lobby |
/lobby name <name> |
Renames the lobby |
/lobby hide|show |
Hides or shows the modded tag in the lobby browser |
/lobby late on|off |
Lets someone join after the game has started, while you're in orbit |
/lobby invite |
Opens Steam's invite window for the lobby (works after the game has started) |
/lobby log [name|file] |
Last notable lobby events (blocks, kicks, bans, joins), one player's, or the log file's path |
Whitelisted friends
Whitelisted players can run stock, time, overtime (/ot), gear, organize, merge,
buy and credits from normal chat,
with no mods on their side. You can change that list with WhitelistedCommands in the config. Those are SimpleSell's commands:
the whitelist lives in SimpleLobby and SimpleSell asks it, so one /whitelist covers both (and SimpleHQ's bank).
/buy works for them before the game has started too, and spends the ship's credits.
If they also have SimpleLobby installed, whitelisted players can:
- pull the lever to start the game before you've started it this session. Normally only the host can do that. The host still checks they're at the lever, in the ship, in orbit.
- move equipment before the game has started: anything that isn't scrap, plus your gear list (e.g. the shotgun). Scrap stays locked until the first landing, as in vanilla.
The host gets the same pre-start equipment allowance. Without SimpleLobby, the friend's own game keeps
the lever and pre-start pick-ups locked; their commands still work. /whitelist add|remove applies
at once to someone who's connected.
During a SimpleHQ tournament every player may pick things up before the lever (SimpleHQ allows it so teams can stage their kit), and SimpleLobby doesn't refuse those pick-ups. The lever rule is unchanged.
If their / commands don't work, another chat mod on their machine is probably grabbing
them. They can type ! instead: !stock, !merge.
Late join
Off by default, and off again every time you start the game. Type /lobby late on and friends can
join your running game whenever the ship is in orbit. The lobby closes when you pull the lever and
opens again when you're back in orbit. Bans, kicks and version checks still apply. Never while
SimpleHQ tournament mode is on.
The game drops its Steam lobby the first time you land. If that has happened, SimpleLobby opens a
new Steam lobby for the game you're already hosting: same name, same privacy and same version.
Friends can find it in the lobby list (public lobbies), use Join Game on your Steam profile,
or be invited with /lobby invite, which opens Steam's invite window. The game's own invite button
is greyed out once the game has started. To turn this off, set [Lobby] ReopenSteamLobby = false.
The joiner arrives in the ship, alive, with the current credits, quota, deadline and moon. If they have SimpleLobby installed, they can pick things up and pull the lever right away. Without it, the game won't let them pick up items until the first landing. Joining while landed isn't possible: the joiner's game would have no moon interior. Someone who tries then is told to wait until the ship is back in orbit.
A late joiner can show up as "unknown" to other players, and see them as "unknown" too, unless they're Steam friends. You as the host always see real names. Players who have SimpleOptimize see real names as well.
Safer joins (0.1.37). Two people joining at the same moment can no longer both get the last slot
and crash the lobby for everyone. Someone who still gets through with no slot left is turned away with
"Lobby is full!", and only them. A joiner whose connection gets stuck (the game can't send them the world,
or they take more than 45 s) is disconnected so they can try again, instead of being retried forever.
Config [Lobby] ReserveJoinSlots, RefuseJoinWithoutSlot, DropStuckJoiners, StuckJoinSeconds,
RepairJoinSync (all on). These protect every join, not only late joins.
The pause menu crew list only shows players who are really in the game. Without SimpleLobby it keeps the names of strangers who tried to join a public lobby and were turned away.
Firewall
Cheat menus don't need networked mods: they send the game's own requests directly. The host now checks who sent each one. Landing needs a lever pull from that player at the lever. Store items, unlockables, the cruiser and routes must be paid for at the terminal. Furniture moves and chat must come from the player they claim to be. Debug commands from other players are refused.
A request no unmodded game can send (a faked player, a debug command, a landing when nobody pulled the lever)
gets the sender banned automatically by their real Steam ID, the same as /ban. Whitelisted players
are never auto-banned. Price mismatches and spam are only refused and logged.
Items too: other players can only drop, place or deposit an item they're actually holding, pick up
items within reach, and put them down near themselves, so client sell and teleport mods can't move
anything. An item only goes on the sell desk if the desk accepted it. Anything stuck there anyway goes
back on the ship by itself ([Firewall] DeskJanitor).
Belt bags follow the game's own rule (non-scrap items only, 15 at most, into the bag in your hand); scrap
sent into a bag anyway counts as forged, and anything a bag shouldn't hold is dropped back out for
everyone ([Firewall] BeltBagVanillaRule). The first forbidden bag attempt only gets a private
warning; repeated attempts ban ([Firewall] BeltBagStrikes, default 3).
Lobby Guard can message a single player privately, which also works for players without mods.
The host's chat box takes up to [Lobby] HostChatLimit characters (default 120), so longer
/lobby name names fit. The game's lobby list shows only the first 40.
Look for [RpcFirewall] in the BepInEx log. Settings are under [Firewall] (BanForgedRpc, BanLeverlessStart, LogAllowed, ...).
Lobby log
Every lobby session is written to BepInEx/config/SimpleLobby/logs/<date>_<time>_<lobby>.jsonl, one event
per line: joins and leaves with both Steam IDs, refused joins, kicks, bans, every firewall block, floods,
command names (never chat text) and ship events. Only on your PC; nothing is sent anywhere. At most 5,000
lines per session; the newest 30 sessions (or 20 MB) are kept. /lobby log shows the latest events in chat.
Scrap guard
Mods like GeneralImprovements (ScrapLeft monitor), ShipLootPlus, DetailedScan or ScanFix tell their player
how much scrap is left inside. The host can't stop those: every player's game already has every scrap
item (the vanilla terminal scan counts them too), and those mods only read that and show it on their own
screen. Hiding the scrap values isn't an option either: the one message that sends them also decides each
item's look and the end-of-day total, so vanilla players would see the wrong grade and wrong models.
What the host can stop is a readout that goes through the host, and that's what the scrap guard does:
- System chat lines from other players are limited to the three a vanilla game sends ("X joined the
ship.", "X was left behind.", "[playerNumN] started the ship."). Anything else, like abu's AutoScan posting
Inside: 23 ≈1450to everyone, never reaches anyone. ([ScrapGuard] VanillaSystemLinesOnly) - Chat that's only a scrap readout (
12 1450, what AutoTerminalScanClassic posts in its Everyone mode) isn't relayed. ([ScrapGuard] BlockScrapReadoutChat) - Mods that ask the host first, like LCBridgeOverlay, get no answer and stay off; the guard names them.
Each catch is reported to you privately (Action = Warn, default), only logged (Log), or kicked (Kick).
Whitelisted players are never kicked by the scrap guard; their scrap readouts are still held back. A typed
"12 1450" is never a kick on its own. Toggle in game with /guard scrap on|off|log|warn|kick. The host's own
lines (every suite plugin's, including SimpleSell's /briefing live) are never checked.
| Mod (downloads, Oct 2026) | How it gets its numbers | Stopped? |
|---|---|---|
| GeneralImprovements (3.2M) | ScrapLeft ship monitor (off by default); counts items on that player's machine, approximate value by default | No: own screen only |
| GoodItemScan (692k) | Totals the items its own scan reaches | No: own screen only |
| DetailedScan (675k), ScanFix (488k), Better Terminal Scanner (19k) | Terminal command on that player's machine | No: own screen only |
| ShipLootPlus (567k) | Moon loot value on its own display | No: own screen only |
| QualityCompany (70k) | Scan module on that player's machine; its networked parts need the host to run it | Scan: no. Network parts: already dead without the host |
| BetterTotalScrap (78k) | End-of-day screen | No (and it's after the day) |
| abu AutoScan (5.6k) | Posts the count to everyone as a system line; off on clients by default (HostOnly) | Yes, the line is blocked and reported |
| AutoTerminalScanClassic (3.4k) | Posts "count value" in chat in Everyone mode (default: only to self) | Yes in Everyone mode, blocked and reported |
| ScrapCounter (0.9k) | HUD on that player's screen | No: own screen only |
| LCBridgeOverlay (1.2k) | Asks the host for permission first | Already off without the host; the guard names it |
Coming from SimpleSell
The first time SimpleLobby runs it copies, from local.simplesell.cfg, every [Lobby] and [Firewall]
setting and [General] CommandPrefix into local.simplelobby.cfg: whitelist, bans, guard mode,
WhitelistedCommands, the alt prefix, the host chat limit, every firewall switch. Same section and key
names. SimpleSell.playerlog.txt (the join log /ban uses for people who already left) is copied to
SimpleLobby.playerlog.txt. SimpleSell's own file is only read; its old lines stay there, so going back
to SimpleSell 0.1.39 still has them. [Migration] ImportedFromSimpleSell = true marks it done.
DeskGuardRange exists in both: SimpleLobby's item firewall uses its copy; SimpleSell's desk-beam check
(used when the item firewall is off) uses [Selling] DeskGuardRange. AutoReturnBeamedItems and /return
stayed in SimpleSell.
SimpleSell 0.1.39 or older still contains all of this. If one of those is installed, SimpleLobby does nothing at all (no patches) and says so once in chat, so nothing runs twice. Use SimpleSell 0.1.40+.
Without SimpleSell, SimpleLobby works on its own. The pre-start equipment allowance then covers non-scrap
items only (SimpleSell's gear list adds scrap like the shotgun), and desk refusals go back to the ship through
the desk janitor instead of /return.
Defaults worth knowing
- The lobby guard flags anyone running networked mods. It only warns unless you switch
it to kick with
/guard. In a lobby where people run other mods, expect it to flag them. - The modded tag is hidden by default (
HideLobbyModTag = true), so your lobby looks vanilla in the browser. Use/lobby showto turn that off. - Late join is off at every launch.
/lobby late onwhen someone needs it. - The scrap guard is on, in warn mode.
Everything is configurable in local.simplelobby.cfg.
Install
Drop SimpleLobby.dll into BepInEx/plugins, or install with a mod manager. Requires
BepInEx 5.4.2100. Works with or without SimpleSell (0.1.40 or newer).
CHANGELOG
Changelog
0.1.9
Host-side security update. Vanilla players need nothing new. Regular modded traffic still passes.
- Connect-time refuse for permanently banned players. Peers on the built-in permanent ban list are refused as soon as Steam identifies them, before their packets are parsed. ConnectionApproval remains a second gate.
- Malformed proxy messages dropped. Proxy messages whose structure cannot be safe to read are dropped and the sender is disconnected on the host (clients drop a bad proxy instead of crashing). Well-formed traffic is unchanged.
- 0.1.8 PacketGuard preserved. Batch structural checks, pre-join caps, and Warn defaults for non-malformed traffic are unchanged. Only malformed or crash packets are hard-blocked.
0.1.8
Security release: a modded joiner could crash the host while joining, before any of SimpleLobby's checks ran.
Regular modded traffic always passes, and every action defaults to Warn. Host-side; vanilla players need
nothing new. New config keys: [Firewall] Action (Warn / Refuse / Ban, default Warn), [NetGuard]
PacketGuard, PreJoinMaxBytes, RefuseMissingSteamId, RequireLobbyMembership (both off).
-
Players' own mods are never blocked. Info mods, custom named / unnamed network messages, large mod messages and the chat or system lines mods post are never dropped, hidden, kicked, refused or banned, under any setting value (
GuardMode = Kick,[ScrapGuard] Action = Kickand[Firewall] Action = Banincluded). They get one info line in the log per player. Before,GuardMode = Kickkicked on the first mod message. -
Warn by default.
[Lobby] GuardMode,[ScrapGuard] Actionand the new[Firewall] Actiondefault to Warn. In Warn the firewall checks and logs (WOULD REFUSE/FORGED, warn mode) but lets requests through, sends no corrections or whispers, counts no belt-bag strikes and bans nobody; the desk janitor, belt-bag clean-up, RPC flood/size limits and spawn caps only log too.Refuseenforces;Banalso auto-bans (BanForgedRpc,BanLeverlessStart,BeltBagStrikes).GuardMode = Kicknow only applies to abuse reports (mass spawns, desk beams, forged requests with auto-ban off). -
Scrap guard only notes.
VanillaSystemLinesOnly,BlockScrapReadoutChatandBlockInfoLeakChatdefault off and, when on, only report to the host; lines are always shown.Action = Kickacts as Warn. -
Join checks warn.
RefuseForgedSteamId,RefuseMissingSteamIdandRequireLobbyMembershipdefault off and logWARN (let in)instead. Your ban list (by Steam's real ID) still applies. -
KickModdedJoinersremoved. -
One-time reset. Existing cfgs are moved to these Warn defaults once (
[Migration] WarnDefaults018); the log lists what changed. Afterwards your settings stay. -
Still always on: the ban list, and the disconnect + lobby refusal for malformed (crash) packets.
-
Malformed packets are stopped before the game reads them. Every network packet from another player is checked for its structure only (header, total size, message count, each message's size) before Netcode parses it. The crash used a message size that turns negative inside Netcode and crashes the game in native code. Such packets are dropped and the sender disconnected and refused for that lobby. Well-formed packets pass whatever they contain, mod messages included. Before being let in, a player also has generous flood limits (1 MB per packet, over Steam's own 512 KB limit; 1000 packets a second, warn only by default).
-
A bad packet can no longer break the host's network loop. An error while reading one player's packet disconnects that player (no ban, no refusal: they can rejoin at once).
-
Steam identity works again. Since SimpleSell 0.1.36 every join logged "Steam identity unavailable", so bans and the whitelist could only use the ID a player's game claims. The ID Steam itself reports is now read from the Steam messages and the Steam connection status. Bans, the whitelist and the forged-ID check use it. With
RefuseForgedSteamIdon, a mismatch is only refused when Steam's ID is in your Steam lobby (otherwise it is logged as a possible misread). -
Join request checks (warn by default). Over Steam, a join request without a Steam ID, or (when Steam's ID can't be read) one whose claimed ID isn't in your Steam lobby, is logged; turn the switches on to refuse.
-
Never auto-banned for reconnecting. A forged-looking request from a player who is still joining, or joined less than 20 s ago, is refused but no longer auto-bans them (a game reconnecting after a crash can still send from its old session). Nothing new in 0.1.8 writes to the ban list.
-
Clients are protected too. As a client, a malformed packet from the host is dropped instead of crashing your game. The host-side check runs on every packet, at any time (in orbit, landed, joining).
-
Big mod messages are fine. A custom message of any size passes (was dropped over 64 KB); over 1 MB it is logged as info.
-
The lobby log keeps the join path. New
handshakeevents (first packet, approval, rejected packets) are written to disk at once, so they survive a crash.
0.1.7
[ScrapGuard] BlockInfoLeakChatnow also drops structured scan/price readouts typed as a player by another mod (e.g. "Scan Info: Prices: Inside: $608 Outside: $447 Bees: 1 [$61] ... Total: [$1055]", one line or several, with or without color tags, "Scrap Info" or no header). Casual talk like "there's like 600 inside lol" still goes through.
0.1.6
New config keys: [Lobby] KeepSteamLobby, [Lobby] FixSlotGaps, [JoinQueue] OneJoinAtATime, MaxQueue,
JoinTimeoutSeconds, BlockLeverWhileJoining, [ScrapGuard] BlockInfoLeakChat (all on by default).
Host-side; vanilla players need nothing new. Four ideas from LobbyControl (MIT, see README Credits):
- One join at a time. The next joiner is let in once the current one's game has reported in (player info, held items, level). Up to 3 wait in line. A joiner who is stuck after 40 s is dropped so they can retry.
- The ship lever is blocked while a player is joining or waiting, with a chat line saying so.
- One Steam lobby for the whole session. It is no longer left at the first landing, only closed while landed, and late join reopens the same lobby instead of creating a new one.
- Vanilla slot-gap bug fixed: players in higher slots are marked present when there's a gap below them.
Anticheat (Josh): chat or system lines from other players that carry info a vanilla player can't get (interior type, inside enemies, item, exit, apparatus or key locations, outside enemy counts that no scan could have shown) or that pose as the system, the host or another player are dropped and reported. Only automated-looking lines are dropped (labelled, repeated, or right after landing). Scrap-count readouts are unaffected by this check.
0.1.5
No new config keys. Optional LethalConfig support: if LethalConfig is installed, SimpleLobby's settings appear in its in-game menu (checkboxes, number fields, a slider for HostChatLimit, dropdowns for GuardMode and Action). Soft dependency only; nothing changes without it. Internal migration flags are not shown.
0.1.4
No new config keys. Built-in permanent bans are now stored only as one-way fingerprints, not readable IDs.
0.1.3
No new config keys. Lobby log fixes from QA:
- A host's lever pull is logged once (it was logged twice, 1 ms apart: send stage and loop-back execute).
session_end"lines" now counts the session_end line itself, so it matches the file.- The session_start mod list is no longer cut short with "…" (it has its own, longer cap).
- The BepInEx log now says when NetGuard's flood/size hook installs, not only when it fails.
0.1.2
No new config keys. Everything below is host-side; vanilla players and friends need nothing new.
- Lobby log. Each lobby session gets its own file in
BepInEx/config/SimpleLobby/logs/(one JSON event per line): session start and end, joins and leaves (name, the Steam ID the game reported and the one Steam gave the connection), refused joins, suite handshakes and recognised mods, kicks, bans, unbans, every firewall block, RPC-flood warnings, command names (never chat text), lever and ship events, and big orders or spawns. Written every 2 s in the background, at most 5,000 lines a session (the last 200 kept for blocks, kicks and bans), 512 bytes a line; the newest 30 sessions or 20 MB are kept./lobby logshows the last notable events,/lobby log <name>one player's,/lobby log fileprints the path to the BepInEx console. One summary line goes to the BepInEx log when the session ends. - Permanent ban list built in: refused at the door by real or
claimed ID, kicked if somehow inside;
/unban, the whitelist and settings can't lift it. Every try is logged. - The terminal can't be deleted or put out of reach. Storing the terminal (or any furniture that can't be stored) is now a forged request: refused and auto-banned, before vanilla's own check. Moving the terminal under the floor or into a wall (more than 1 m outside the ship room) is refused; more than 10 m outside is forged. Rotating the terminal and furniture is vanilla and stays allowed.
- Terminal lock-out closed. "Terminal in use" from someone who isn't at the terminal (which kicked whoever was using it off) is refused; the terminal-values and terminal-sound requests are rate-limited, and a sound number the terminal doesn't have (which threw an error on every game) is refused.
- Flood limit. Every request a client sends is counted per second: over 150/s is logged, over 400/s the rest of that second is dropped, and 400/s for 3 seconds in a row or 1,200 in one second is a kick. Normal play is a few tens a second. Whitelisted players are never kicked by it.
- Oversized messages dropped: a game request over 16 KB, or a mod message over 64 KB, from a client.
- Giant-text chat crash closed. Rich text (
<size>,<sprite>,<voffset>...) is removed from other players' chat before it is relayed, and a system line with rich text (e.g. a fake "<size=...> joined the ship.") is refused. - Mass spawn and despawn cap. More than 30 spawns or 20 despawns in 10 s caused by one client's requests are cancelled. Clients can no longer despawn enemies (no vanilla game does), delete a held item that isn't a used key, destroy an inventory item that isn't a shotgun shell, or repeat the sell-desk "done" message to clear the desk early.
- Ship controls checked: doors, magnet, lights, teleporter button and alarm horn need a living player in the ship and are rate-limited; the unlockable and suit sync requests are rate-limited (the host answers them to everyone).
0.1.1
- Belt bags may hold the Vesper Gold nugget (Josh's decision). It is a native SimpleMoons item, and
SimpleMoons lets belt bags take it. Before, the firewall's vanilla belt bag rule threw it out of bags
every 2 s, and a client who bagged one got a forged-request strike that leads to a ban. A new config
entry,
Firewall / BeltBagAllowedScrap(default51020=Gold nugget, so item id 51020 AND the name Gold nugget must both match), is exempt from both the 2 s sweep and the host's forged-request check. All other scrap is still forbidden, and the 15-item limit and the other bag checks are unchanged.
0.1.0
- New plugin, split out of SimpleSell 0.1.39. Everything about running the lobby moved here unchanged:
the whitelist and its perks, bans (by real Steam ID), Steam identity checks, the lobby guard, the RPC and
item firewall (lever, purchases, routes, furniture, chat, items, sell desk deposits, belt bags, desk janitor),
late join and reopening the Steam lobby, safer joins, the invisible-joiner and crew-list fixes, the join log,
the hidden mod tag, the longer host chat box, and the commands
/lobby,/players,/kick,/guard,/whitelist,/ban,/unban,/bans./help lobbylists them. - Settings come across by themselves. On the first run every
[Lobby]and[Firewall]setting and[General] CommandPrefixis copied fromlocal.simplesell.cfg(same names), and the join log fromSimpleSell.playerlog.txt. SimpleSell's file is only read. - No double running. Next to SimpleSell 0.1.39 or older (which still has all of this) SimpleLobby does nothing and tells the host once. With SimpleSell 0.1.40 each plugin answers only its own commands; one whitelist covers both (SimpleSell asks SimpleLobby), and SimpleHQ's bank still finds it through SimpleSell.
- Works without SimpleSell too. The messages a whitelisted friend's game receives keep their old names
(
SimpleSell.Trust,SimpleSell.LateSync), so friends on SimpleSell 0.1.38/0.1.39 keep their perks. - New: scrap guard (
[ScrapGuard], on, warn). Other players' games may only post the system chat lines a vanilla game sends, and a chat line that is only a scrap readout isn't relayed, so client mods that post interior scrap counts to the lobby (abu AutoScan with HostOnly off, AutoTerminalScanClassic in Everyone mode) reach no one, and you're told who. LCBridgeOverlay (which asks the host first, and stays off here) is named in the report. ActionLog | Warn | Kick; whitelisted players are never kicked by it./guard scrap on|off|log|warn|kick. Counters that only show numbers on their own player's screen can't be stopped by a host (every game already has the scrap; the vanilla terminal scan counts it too); see README. - Lobby guard reports now name a known mod when its message is recognised.