R.E.P.O.
Install with App

Details

Latest version
1.2.1
Last Updated
First Uploaded
Downloads
945
Likes
1
Size
125KB
Dependants

R.E.P.O Fixes+

Small, independent fixes for problems that show up in modded R.E.P.O lobbies - especially big lobbies with late joiners. Every fix has its own on/off switch, and fixes aimed at another mod only switch on if that mod is installed.

What it fixes, in plain terms

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.
  • 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 code kept looking for your character for a second after you left, throwing about 40 errors each time. 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.
  • 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.)
  • 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.
  • LateJoinNow keeps your equipped gear - With LateJoinNow, anything in your belt slots used to be deleted on every level change. Equipped gear now survives.

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.
  • 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.
  • 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.
  • 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.

Turn any of these off in BepInEx/config/ricketywrecked.repo.fixesplus.cfg, or through REPOConfig in-game. Restart the game after changing.

For the technically curious

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. 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.

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.

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.

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.OnObjectsFound postfix (Hauler Unlimited Storage replaces it and lists every object; vanilla's absorb step then destroys anything without a ValuableObject for $0) - removes non-valuables from validObjectsInBox.
  • Prefix on CrouchAndCrawlSprint's PlayerController.Update postfix - skipped until playerAvatarScript, PlayerCollisionStand.instance and CameraCrouchPosition.instance exist (SetCrawl dereferences them unguarded).
  • EnergyUI.Start postfix re-runs Toggle Mute's own HUD setup if its MutedText object doesn't exist yet.
  • Prefix on CartSpeedSync's CartSteer postfix - 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.
  • Postfix on Photon's Player.InternalCacheProperties (GameTools only): GameTools obeys GT_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.
  • 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.

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)
EnemyAttackFix on Slow Walker stuck mid-attack
LevelTeardownErrorGuards on Teardown errors (tumble wings, room lighting after leaving), per-frame errors from a character that never finished setup, and the revive camera cleanup
OtherModGuards on Fixes for other installed mods (list above)
GameboyPauseWhenIdle on Pause Empress Gameboy when nobody's playing
ConnectionTimeoutSeconds 30 Seconds before a connection hiccup disconnects you (10 = game default)
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.

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.

Thunderstore development is made possible with ads. Please consider making an exception to your adblock.