
REPO Fixes Antispam Latency Fix
Fixes the bugs that wreck modded R.E.P.O lobbies: error floods and stutter, enemies stuck mid-attack, locked extractions, lost slot items, timeout kicks, and bugs in popular mods. Every fix can be switched off. Only you need it.R.E.P.O Fixes+
Fixes the bugs that wreck modded R.E.P.O lobbies. Error floods and stutter, enemies stuck mid-attack, extractions that won't open, items lost between levels, timeout kicks, and bugs in popular mods. Every fix has its own on/off switch, and only you need the mod.
Highlights
- Less stutter. Stops the error floods (thousands of errors a minute) that make big lobbies hitch, from late joiners, level changes and players leaving.
- Nothing gets stuck. Slow Walkers stuck mid-attack, Spewers left on your face, revive items stuck on a player who left, and extraction points locked for the rest of the level are all fixed.
- Keep your gear. Items in extra slots (4+) and items spawned by admin mods come with you to the next level. Bought items no longer end up outside the truck.
- Fewer timeout kicks. A short internet hiccup no longer throws you back to the menu.
- Instant grab beam. Your own grab beam reacts the moment you click.
- Fixes for other mods. Bugs in GameTools, Hauler Unlimited Storage, Toggle Mute, CartSpeedSync, Crouch And Crawl Sprint, XH DamageShow, Empress Gameboy and Repo Admin Menu, each only active when that mod is installed.
Who needs it
Just you. Most fixes work best on the host (marked "host" below), but nobody else in the lobby needs the mod, and it never changes who can join.
Everything it fixes
Lag and errors
- Late joiners (enemy tracker fix) - Someone joining a match already in progress used to make every enemy throw an error each time it tried to see or track them. Over a long session that adds up to heavy stutter or a stuck loading screen. Fixed.
- Error storms when a level ends - When a level is torn down, some game code keeps running for a moment after the things it reads are gone: grab beams, eye tracking, held melee weapons, the tumble wings upgrade. Each error is a full stack-trace write to the log - thousands of them in a few seconds shows up as a hitch. These are caught quietly now.
- Stuck Slow Walker - If a player left while a Slow Walker (Trudge) was vacuuming them, it got stuck mid-attack and threw an error every frame until the level ended (4,000+ errors from one enemy). It now carries on normally.
- Spewer stuck on your face - If the level changed while a Spewer was latched onto a player, its mouth stayed attached into the next level (the shop) and threw an error every frame. It is now removed the way the game would have removed it.
- Error flood from one player's character - When a character never finishes setting up on your side (seen when someone in the lobby is on a different game version, and with the character preview in menus), the game threw an error for it every frame: 9,000+ in under three minutes. The preview is now linked up properly, and any other broken character is skipped quietly instead.
- Revive finishing properly - Being revived could crash the spectator camera's cleanup, which also skipped the rest of the revive (the short movement lock, crouch/energy reset and heal effect). The cleanup now finishes and the revive completes.
- Leaving a match - The room-lighting and fog code kept looking for your character for a second after you left or were kicked, throwing up to ~170 errors each time. Caught quietly now.
- Truck error - Every time the truck between levels loaded, the game's enemy director threw an error (the red one in the console). The truck has no enemies, so nothing depended on it; it's caught quietly now.
- Stuck revive item - If the downed player the revive item locked onto left the game, it got stuck and spammed errors every frame. It now lets go and looks for someone else.
- Player leaving while holding a door - If a player left (or was kicked) while holding a door, lever or other fixed object, the host's game threw an error every frame until the level ended (10,000+ in three minutes). Players who left are now dropped from it.
- Joiners' upgrades and deaths - A joiner's grab strength, throw and range upgrades weren't applied when their Steam ID arrived a moment late, and a player dying before their colours arrived left their body standing. Both are fixed.
- Lighter logging - Unity normally captures a full stack trace for every ordinary log line and warning, which creates garbage-collection stutter in heavily modded games. Errors keep their stack traces.
Gameplay
- Instant grab beam - Your own grab beam turns on and off the moment you click instead of visibly lagging behind in multiplayer. Other players don't need the mod.
- Extra inventory slots keep their items - The game only remembers slots 1-3 between levels. With a mod that adds slots (like ExtraSlots), anything in slot 4+ used to be left behind. It now comes with you. (Only the host needs this.)
- Spawned items stay yours - Items spawned by a mod (like Repo Admin Menu's spawn menu) disappeared at the next level and could take over items players already had in their slots. They now count as owned, like shop items, and come back in the truck (host).
- Bought items back in the truck - With NoItemSpawnLimit and more items than the truck has spots for, the extras came back outside the truck or inside a wall. They're now put on top of the truck's spots instead (host).
- Fewer timeout kicks - The game gives up on the connection after 10 seconds without an answer, so a short Wi-Fi or internet blip could kick you - even from your own lobby. This raises it to 30 seconds (adjustable). A long outage still disconnects.
- Extraction points stuck locked - When someone joined mid-level after the first extraction was finished, their game could make the host start that finished point again, which locked every other extraction point for the rest of the level (nobody could open the next one). The host now only starts a point that's ready. Only the host needs this; it works for players without mods.
- Joining a late-join lobby that just closed - Hosts with a late-join mod close their lobby for a few seconds while a level loads, so picking it from the server list often failed with "Game closed" (or "Game full") and sent you back to the main menu. The join is now retried every 5 seconds, up to 4 times.
- LateJoinNow keeps your equipped gear - With LateJoinNow, anything in your belt slots used to be deleted on every level change. Equipped gear now survives.
- LateJoinNow voice for players without mods - When someone without LateJoinNow joins mid-level, LateJoinNow tries to send them the other players' voice chat objects, but Photon refused that message every time, so they could be missing voices. It now goes through.
- LateJoinNow in private lobbies - In a private (friends-only) game, LateJoinNow mistook the open lobby for a locked one and re-opened it with Steam every 5 seconds for the whole session. It now only does so when the lobby really was locked.
Want friends to join mid-level, with no invisible rooms? That's our late-join mod: LateJoinPlus.
Fixes for other mods (each only active if that mod is installed)
- Hauler Unlimited Storage - it lets everything into the hauler, and the game then absorbs non-valuables for $0 and deletes them - guns, tools, drones, purchased gear. The hauler only takes valuables again, still with no limit.
- XH DamageShow & EnemyHealthBar - it shows a Chinese welcome message ("welcome to the monster health bar mod, sponsored by ...") in the middle of the screen the first time an extraction point opens each game. That popup is hidden; health bars and damage numbers are unchanged.
- Crouch And Crawl Sprint - with crawl left toggled on (LeftAlt - easy to hit while alt-tabbing), it threw an error every frame during level loading. It now waits until the level is ready.
- Toggle Mute - its MUTED indicator never appeared because it looked for a HUD element before the game had created it. It shows up now. Prefer no on-screen text? Set
ToggleMuteShowIndicatorto off: the text (and Toggle Mute's error about it) goes away and the mute toggle keeps working. - CartSpeedSync - it pushed velocity onto carts this machine doesn't simulate, filling the log with physics warnings that grew every level. Those no-op calls are skipped.
- GameTools - it re-sent a lobby setting to every player every 3 seconds all session, even though it never changed. It only sends when it changes now. It also let any player who has GameTools kill, revive or heal you remotely, and a kill and a revive requested at the same time looped (71 deaths in 7 seconds in one lobby). Now only the lobby host can, and a kill + revive at the same time is ignored. When you host, it works for everyone else as before. And its "revive at extraction point" fired even while an extraction was running, so the revived player was killed again by the tube and the game's own end-of-extraction revive then missed them; it now waits, and the game revives them when the extraction finishes. Its "revive when head is on a cart" also revived a player who died in a cart on the spot - in whatever had just killed them - so they died again a second later; that cart revive now waits until their head has been taken out and put back.
- Empress Gameboy Emulator - the host emulated the game and streamed its screen to every player all session, even with nobody playing. It now pauses (screen goes dark) while nobody's at the controls and resumes on E.
- Repo Admin Menu - its per-player checks threw an error when someone joined (their Steam ID wasn't known yet), skipping the game's own update for that frame. Fixed.
Turn any of these off in BepInEx/config/ricketywrecked.repo.fixesplus.cfg, or through REPOConfig in-game. Restart the game after changing.
Settings
| Setting | Default | What it controls |
|---|---|---|
EnemyTrackerFix |
on | Late-joiner enemy tracker fix |
GrabBeamAntispam |
on | Grab beam / eye tracking / held-object error guards |
InstantGrabBeam |
on | Instant local grab beam |
ReviveItemFix |
on | Revive item stuck on a player who left |
LateJoinNowEquippedItemFix |
on | Equipped gear survives level changes (needs LateJoinNow) |
LateJoinNowVoiceFix |
on | Voice objects reach late joiners without mods (needs LateJoinNow) |
LateJoinNowPrivateLobbyFix |
on | No lobby re-open every 5 s in private games (needs LateJoinNow) |
ServerListJoinRetry |
on | Retry "Game closed" / "Game full" joins from the server list |
EnemyAttackFix |
on | Slow Walker stuck mid-attack; Spewer mouth left on a player after a level change |
LevelTeardownErrorGuards |
on | Teardown errors (tumble wings, room lighting and fog after leaving or a kick, enemy director in the truck), per-frame errors from a character that never finished setup, and the revive camera cleanup |
OtherModGuards |
on | Fixes for other installed mods (list above) |
ToggleMuteShowIndicator |
on | Toggle Mute's on-screen MUTED text (off = no text, toggle still works) |
GameboyPauseWhenIdle |
on | Pause Empress Gameboy when nobody's playing |
ConnectionTimeoutSeconds |
30 | Seconds before a connection hiccup disconnects you (10 = game default) |
SpawnedItemsKeep |
on | Mod-spawned items count as owned and come back next level (host) |
TruckItemsKeep |
on | NoItemSpawnLimit's extra bought items go on top of truck spots, not outside the truck (host) |
ExtractionSoftlockFix |
on | Don't restart a finished extraction point when someone joins mid-level (host) |
ExtraSlotsKeepItems |
on | Items in slot 4+ carried to the next level (host) |
NoStackTracesOnInfoAndWarnings |
on | Lighter logging (Performance section) |
If anything about grabbing feels off in your lobby, turn off InstantGrabBeam first.
Good to know
- Grabbed objects can still feel delayed when you're not the host - the host runs physics and streams the result, and this mod doesn't change that.
- A fix that can't apply (for example after a game update) is logged and skipped; the others still load.
- Only needs BepInEx. Built and tested in a heavily modded 10-player profile on R.E.P.O v0.4.4.3.
- Other players don't need this mod, and having it or not doesn't affect who can join.
Technical details
Enemy tracker fix (late joiners)
The base game registers each player with every enemy's vision tracking once, when the level's first enemy wave finishes spawning. Anyone who joins after that, or any enemy that spawns after they joined, is never registered, and every vision/on-screen check for that player throws KeyNotFoundException. This registers joining players with every enemy tracker, registers current players with each new tracker, and self-heals EnemyOnScreen.GetOnScreen. It only calls the game's own registration method; nothing polls.
Teardown and grab error guards
PhysGrabBeam.DrawCurve gets the null checks it was missing. PlayerHealth.Update gets a prefix: a menu avatar whose playerAvatar is still null (its Awake read PlayerAvatar.instance before it existed) is linked to the local player once it exists, and skipped until then. A finalizer backs it up for any other avatar that never finished setup, and its warning names the player. SpectateCamera.StopSpectate (called from ReviveRPC) can throw on its second-to-last line when normalTransformPivot is already destroyed, which also aborted the rest of ReviveRPC. A finalizer destroys the spectate camera object itself and lets the revive continue. EnvironmentDirector.AmbientLightLogic gets a finalizer for the frames after the local player is gone. EnemyDirector.Start throws a NullReferenceException on every truck (Level - Lobby) load; a finalizer absorbs it (it only sets the enemy spawn-pause timer, unused in the truck). PlayerEyes.LookAtTransform, PlayerEyes.ClosestPhysGrabPoint, PhysGrabObject.PhysicsGrabbingManipulation, PhysGrabber.OverrideDisableGrabLookAt and ItemUpgradePlayerTumbleWingsLogic.FixedUpdate get Harmony finalizers: all are void and run every frame or physics tick, so absorbing an exception from an object that's already gone has no gameplay effect. The mod's own "suppressed" log lines are rate limited (first occurrence, then every 1000th).
Slow Walker
SlowWalkerAttack.SuckInListPlayerUpdate rebuilds its in-range player list each frame and reads each player's PlayerVisionTarget.VisionTransform unguarded. The throw happens partway through StateImplosion, so the state machine never advances and the enemy rethrows forever. A finalizer on the callee returns control to StateImplosion so it keeps going.
Spewer
EnemySlowMouthAttached sits on the player's avatar, which survives level changes. When the enemy is unloaded mid-attach, its Update throws on destroyed eye/particle references before it reaches StateOutro, its only self-destroy. A finalizer swallows that and, once the parent EnemySlowMouth is gone, destroys the jaws and the component the way StateOutro does.
Revive item
ItemReviveItem reads its target's death head rigidbody every frame with no null check. When the target is gone this clears playerTarget/hasTarget and tells other players via the game's own UpdatePlayerTargetRPC(-1).
Instant grab beam
PhysGrabBeamActivate/Deactivate send their RPC to RpcTarget.All, including yourself, so your own beam waits for a network round trip. This runs the RPC body locally and sends the same RPC to RpcTarget.Others. Its prefixes run at low priority so other mods patching the same methods (CustomGrabColor reads physGrabBeamActive to detect a first activation) see the state from before activation.
Extraction softlock
TruckDoor.Update on every client calls ActivateTheFirstExtractionPointAutomaticallyWhenAPlayerLeaveTruck once, 2 s after the level is generated, when not every player is in the truck. On a late joiner the nearest point is still Idle and unlocked until the host's state reaches them, so OnClick sends RequestExtractionPointActivationRPC for a point that's already Complete. The host only checks extractionPointActive, then ButtonPress does nothing (not Idle) while ExtractionPointsLock locks every other point. As master, prefixes on RequestExtractionPointActivationRPC and ExtractionPointActivate now skip a point that isn't Idle or is locked. Skipped when LateJoinPlus is installed (it has the same check).
Extra slots
Vanilla stores held items in StatsManager.playerInventorySpot1/2/3 (steamID → instance-name hash); PlayerInventoryUpdate ignores spot indexes above 2 and PunManager.SetItemNameLOGIC only checks those three when re-equipping spawned items. This keeps host-side records for spot 3+ and re-equips with the same ItemEquippable.RequestEquip(spot, player) vanilla uses, after the slot exists. Cleared where vanilla clears its own (StuffNeedingResetAtTheEndOfAScene, ResetAllStats).
Connection timeout
Photon disconnects when a reliable command is unacknowledged for DisconnectTimeout (default 10 s) or resent more than SentCountAllowance times (PUN sets 9). Both are raised (to the configured seconds and PUN's max of 10) from GameDirector.Start once connected, on this machine only; the initial connect is untouched. Photon's server-side timeout still applies.
Server list join retry
A prefix on NetworkConnect.OnJoinRoomFailed: for joins from the server list (DataDirector.networkJoinServerName) failing with GameClosed (32764) or GameFull (32765), it re-issues PhotonNetwork.JoinRoom on the same room every 5 s (up to 4 times) while connected to the master server, instead of the popup and leave-to-menu. Everything else goes to the game's normal handling.
LateJoinNow private lobbies
LateJoinNow re-checks every 5 s whether the Steam lobby is locked by reading SteamManager.privateLobby, which the game also sets in UnlockLobby(false) for private games. Postfixes on SteamManager.LockLobby/UnlockLobby record the real state, and a prefix on its IsSteamLobbyActuallyLocked answers with it.
LateJoinNow voice for players without mods
In its non-coop late-join path LateJoinNow re-sends each existing player's Voice object as a PUN Instantiation event (code 202) through the public PhotonNetwork.RaiseEvent, which rejects every code of 200 or above. A transpiler on its RefreshOldPlayersForNewJoiner coroutine sends that one event (code 202 with prefab Voice, nothing else) through PUN's internal RaiseEventInternal instead. PhotonNetwork itself is not patched.
LateJoinNow equipped items
LateJoinNow destroys non-persistent networked objects on level change; its keep-list (BuildPlayerPersistentViewIdSet) only covers player avatars. A postfix adds every item whose network-synced ItemEquippable.isEquipped flag is set. Found by name at runtime - no compile-time reference to LateJoinNow.
Other-mod guards
All found by name at runtime and applied only when BepInEx reports the mod loaded:
ItemValuableBox.OnObjectsFoundpostfix (Hauler Unlimited Storage replaces it and lists every object; vanilla's absorb step then destroys anything without aValuableObjectfor $0) - removes non-valuables fromvalidObjectsInBox.- Prefix on CrouchAndCrawlSprint's
PlayerController.Updatepostfix - skipped untilplayerAvatarScript,PlayerCollisionStand.instanceandCameraCrouchPosition.instanceexist (SetCrawldereferences them unguarded). EnergyUI.Startpostfix re-runs Toggle Mute's own HUD setup if itsMutedTextobject doesn't exist yet. WithToggleMuteShowIndicatoroff, a prefix skips that setup instead, keeping only its chat-box lookup (Settings.ChatGameObject, used so typing in chat doesn't toggle mute).- Prefix on CartSpeedSync's
CartSteerpostfix - skipped when not host or the cart rigidbody is kinematic (vanilla guards both). - Prefix on GameTools'
SyncProhibitOthersToRoom- skipped when the room already holds the current value. - Prefix on GameTools'
PlayerDeathHeadupdate postfix - skips its auto revive while the head is in an extraction point whose state isn't Idle/Active (the same rule vanilla's revive item uses), so the extraction revives it after the tube. - A second prefix on the same postfix: for each death it checks
PlayerDeathHead.triggeredPosition(where the player died). If that was within 0.8 m of a cart (GameTools' own test), the cart revive is held until the head has been out of every cart once. Truck and extraction-point revives are untouched. - Postfix on Photon's
Player.InternalCacheProperties(GameTools only): GameTools obeysGT_ReqKill_/GT_ReqRevive_/GT_ReqHeal_<actor or steamID>found in any player's properties. Requests aimed at this player are dropped from the local cache unless they come from the current master client, and a kill + revive pair is dropped entirely. Requests aimed at other players are untouched. - XH DamageShow & EnemyHealthBar (
com.XhPlugin.Repo_Mod): its welcomeUIFocusTextis guarded by a staticonceflag inExtractionPoint_Patches; that flag is set to true at start, so the popup never shows. Nothing is patched. - Prefix on Empress Gameboy's
TickHostEmulator- skips emulation and frame streaming while nobody controls the cabinet; flushes the save, blanks the screen and sends one dark frame when it goes idle.
Logging
Application.SetStackTraceLogType is set to None for Log and Warning; Error/Exception are unchanged.
License
Copyright (c) 2026 RicketyWrecked. All rights reserved. You may download and play with this mod, and list it as a dependency in your own Thunderstore modpack. You may not copy, modify, decompile, reuse or re-upload any of it without written permission - see the included LICENSE file. Permission requests: Discord.
Credits
Made by RicketyWrecked. Not affiliated with the R.E.P.O developers or any of the mods mentioned above.
Questions, bug reports, or suggestions: Discord.