Ralsei-RepoBots icon

RepoBots

Bot teammates that play like real players: explore, haul loot to extraction, run from monsters, carry dead teammates' heads, talk through in-game chat with TTS and take chat orders. Host a lobby; everyone needs the mod.

By Ralsei
Last updated 2 hours ago
Total downloads 8
Total rating 0 
Categories Mods Server-side AI Generated Quality Of Life
Dependency string Ralsei-RepoBots-0.7.2
Dependants 0 other packages depend on this package

This mod requires the following mods to function

BepInEx-BepInExPack-5.4.2305 icon
BepInEx-BepInExPack

BepInEx pack for Mono Unity games. Preconfigured and ready to use.

Preferred version: 5.4.2305

README

RepoBots

Bot teammates for R.E.P.O. that play like real players.

A bot is a real PlayerAvatar — same robot body, name tag, colour, health bar, death head and grab beam as a human. The game treats it like a remote player who's on a laggy connection: monsters see, chase and hurt it, it shows up in spectate, it has to be in the truck before the level can end, and when it dies its head drops so you can carry it to extraction to revive it.

The host runs every bot's brain and streams its movement to everyone else.

Status: v0.3.2, loads and hosts in-game; bot behaviour still being tested. It compiles and every Harmony patch applies cleanly against a decompiled (older, April 2025) Assembly-CSharp.dll, but it hasn't been run inside the game yet. Expect a round or two of fixes — see Reporting problems.


What bots do

Situation Bot behaviour
Level starts Joins ~3 s after load next to the host, says hi, looks around the truck
Exploring Builds its own map room by room (it starts knowing only the truck area), heads for the edge of what it knows, glances around as it walks. It can only route through rooms it has explored, so it can get lost
Sees loot Only loot in front of it with nothing in the way (or right next to it). Calls it out, pings it on the map, walks over, faces it, grabs it with the normal grab beam
C.A.R.T. One bot takes a cart, pushes it while exploring, parks it to fetch nearby loot, loads it, and pushes it into extraction at CartLoadTarget items
Hauling Carries it at a slower pace into its cart or to an extraction point it has found (searches for one if it doesn't know any), waits if the loot snags, presses the extraction button itself if none is active
Extraction running Steps off the platform (the tube hurts) and waits with any loot until the next point opens
Monster seen / heard / hunting it Shouts, drops loot (keeps heads), sprints away to somewhere it knows, then crouches for a bit once it's lost it
Hit by a cart, thrown object or tumbling player Gets knocked over (the game's tumble) and gets back up when it settles; walking into it shoves it
Teammate dies Picks up their head and carries it to extraction so they get revived
Hurt Takes real damage from monsters and traps, gets knocked down by big hits, "Ow!", flees from whatever hit it
Dies Normal death: head drops, it can be revived by extracting its head
All extractions done Heads into the truck and waits. Once everyone alive is aboard a bot uses the truck screen; if people don't come back within TruckWaitTime it warns, then leaves without them (the game's own rule for anyone outside)
Player walks up and stares at it Double-crouch greeting
Everyone else is dead Keeps going (and can revive you), but gives up after BotsGiveUpAfter seconds so the run can end

Chat commands

Type in the normal in-game chat. Address one bot by name (clanker follow), all of them (bots follow, everyone stay), or the nearest one (bot follow).

Say Effect
follow, with me, on me Follows you, sprints to catch up, crouches when you crouch
come, come here, over here Walks to where you are and waits
stay, wait, hold, stop Holds its current position
loot, explore, go, resume Back to playing on its own
truck, go back, return Goes to the truck
drop, let go Drops what it's holding
status, report, how much Says the haul, what it's doing and its HP

Bots talk like players

Each bot gets its own voice object (the same one every player has, with the microphone part switched off) and talks through the game's normal chat, so lines are spoken by TTS from where the bot is standing, with the floating chat text above its head, mouth movement, and a whisper when it's crouching. Monsters can hear it too.

What they say: "I found something!" (or "I found something worth about three grand!"), "There's a Huntsman! Run!", "Oh no, Sam is down!", "Hang on Sam, grabbing your head!", "Taking this to extraction.", "That's everything, back to the truck!", replies to your commands, and the odd bit of idle chatter. All the lines are in src/BotLines.cs if you want to rewrite them.

The voice takes ~3 seconds to set up after a bot joins; anything it says before that shows as a speech bubble instead. Turn TTS off with Chat.UseGameChat = false.

Keys (host)

Key Action
F6 Add a bot (it stays for the whole session, max 6)
F7 Remove the newest bot for good
F5 Debug overlay: each bot's mode, task, target, path progress, HP

Install (try it now)

  1. In r2modman / Thunderstore Mod Manager: Settings → Import local mod → pick RepoBots-0.3.2-prebuilt.zip.
  2. Everyone in the lobby needs the mod. Players without it see the bot frozen at the spawn.
  3. Host a lobby (a private lobby on your own works — singleplayer mode isn't supported) and start a level.

The prebuilt DLL was compiled against an older game version. At startup RepoBots checks that everything it uses still exists in your game. If not, it switches itself off (the game is unaffected), shows a red notice in the corner, and lists what changed in LogOutput.log under RepoBots ... doesn't match this version of R.E.P.O.. Send that list, or build from source against your own game files (below), and the compiler will point at the same things.

Build from source

Needs the .NET SDK (6 or newer) and R.E.P.O. installed.

# default GameDir is C:\Program Files (x86)\Steam\steamapps\common\REPO
dotnet build -c Release -p:GameDir="D:\SteamLibrary\steamapps\common\REPO"

Or copy GameDir.props.user.example to GameDir.props.user and set GameDir (and optionally ProfileDir to your r2modman profile so every build is copied straight into BepInEx/plugins/RepoBots).

package.ps1 builds and zips a Thunderstore package into dist/.

The game assembly is publicized at build time (BepInEx.AssemblyPublicizer.MSBuild), so the code reads the game's internal fields directly.


How it works

Host                                             Every client (incl. host)
────                                             ─────────────────────────
PhotonNetwork.Instantiate(PlayerAvatar,          PUN builds the avatar → our PhotonView patch
  data: ["RepoBots.v1", name, id, colour])  ───► sees the marker and forces IsMine = false
                                                 before any Awake runs → game code takes the
BotBrain (host only)                              "remote player" path for it everywhere
  think 5 Hz: threats → truck → mode → loot
  act every frame: navmesh path, look, grab     BotPuppet writes position / look / stance /
  publishes BotState ───────────────────────►     velocity / grab puller into the same fields
                       RaiseEvent @ 20 Hz         PlayerAvatar.OnPhotonSerializeView fills

Patches (each one separately, so a game update only breaks the feature it touches):

Target Why
PhotonView.ControllerActorNr setter Keep bot views "not mine", even on the host who owns them
PlayerAvatar.Awake Register the bot, set its name / steam id, add the puppet
PlayerAvatar.Start + LevelGenerator.PlayerSpawn A late-joining avatar makes the host re-run PlayerSpawn, which teleports everyone back to the truck. Skipped for bots; their death head + tumble body are created separately
PlayerAvatar.OutroStartRPC The level only ends when every avatar reports outroDone
PlayerHealth.HurtOtherRPC / HealOtherRPC Damage/heal normally applies on the avatar owner's machine. The host applies it for bots
PlayerAvatar.ReviveRPC / PlayerDeathRPC / SpawnRPC Keep the brain in sync with deaths, revives and teleports
SemiFunc.PlayerGetName Names come from the Photon owner, which for a bot is the host
StatsManager.SaveGame Keep bots out of your save file's player list
PlayerAvatar.ChatMessageSendRPC Chat commands
PlayerVoiceChat.Start Bot voice objects: microphone off, never block chat

Grabbing goes through the game's own grab system (GrabLink → GrabStartedRPC → beam RPCs, then the master's physics pulls the object to the bot's puller point), so the beam and "who's holding what" look normal to everyone.


Config

BepInEx/config/Jillybob.RepoBots.cfg (also editable in r2modman's config editor).

Section Key Default
General BotCount 1 Bots per level (1–4)
General AutoSpawn true Join automatically each level
General SpawnInLobby true Also join in the lobby menu, truck and shop
General DefaultMode Loot Loot / Follow / Stay / Truck
General BotNames Clanker,Rusty,…
Behaviour FleeEnemies true
Behaviour DangerRadius / SafeRadius 8 / 16 When to run, when it's safe
Behaviour RescueHeads true Carry dead teammates' heads to extraction
Behaviour ActivateExtraction true Press the extraction button
Behaviour MaxCarryMass 3.5 Skip heavier loot
Behaviour CheatKnowAllLoot false Know where all valuables are
Behaviour UseCart / CartLoadTarget true / 3 Push the C.A.R.T., items before taking it to extraction
Behaviour TruckWaitTime 120 Seconds to wait at the truck before leaving (0 = forever)
Behaviour HideFromMonsters true Hide from monsters that aren't after them instead of always running
Behaviour BotsShop / BotsPressShopButton true / true Buy an upgrade each in the shop, press the buy button
Behaviour OpenContainers true Open cabinets / lids they pass
Behaviour PlayMinigames true Fight in the arena after a failed run
Behaviour Trolling / TrollChance true / 0.15 Pranks, chance per minute near a human
General LobbyComeAndGo / LobbyLeaveChance true / 0.2 Bots leave and new ones join in the lobby menu
Chat Conversations / ReplyToChat true / true Bot-to-bot chats, answering what you say
Chat UseExpressions true Use the game's face expressions
Behaviour GiveUp / GiveUpSelfDestruct true / true Give up when they think the quota can't be made, and self-destruct (say "no" / "stop" to cancel)
Behaviour AskForHelp true Go for heavy loot, ask for help and help each other carry it
Behaviour HealTeammates true Share health with hurt teammates ("heal me" in chat)
Behaviour Stamina true Sprinting uses energy like a player's
Behaviour SelfDestructWhenHumansDeadAfter 0 Self-destruct this long after every human dies (0 = never)
Behaviour SplitUp / SplitChance true / 0.5 Sometimes split up and take a side of the level each, then regroup
Behaviour FooledByFellowDroid true With Fellow Droid installed, bots don't run from a disguised droid until it comes for them
Movement WalkSpeed / SprintSpeed / CarrySpeed 2.6 / 4.4 / 2.1 m/s
Movement FootOffset 0 Fix floating / sinking
Chat Chatty / ChatCommands true / true
Chat UseGameChat true Talk through game chat + TTS (false = speech bubbles)
Chat ChatCooldown 7 Seconds between unprompted lines
Advanced EventCodeBase 180 Photon event codes 180–183
Advanced VerboseLogging false Log every decision
Advanced SkipCompatCheck false Load even if the startup check finds game changes (testing only)

Known limitations

  • Singleplayer isn't supported — host a private lobby instead.
  • Everyone needs the mod, or they see a frozen bot.
  • Bots move along the navmesh, so they don't jump or climb. They push doors and props but can't vault over things. Enemy grabs that pull a player around on their own client don't move bots.
  • Bots buy and use upgrades and use weapons in the arena, but don't use other items (flashlights, drones, grenades) during levels.
  • Bots play both after-failure minigames (arena fight and scooter race), but they drive fairly simply: no boost pads or deliberate drifting.
  • Big two-person valuables are skipped (MaxCarryMass).
  • Enemies that hook into a player's voice chat may misbehave around bots.

Reporting problems

Turn on VerboseLogging, play until it goes wrong, then send:

Don't copy the log out of the black BepInEx console window: it only keeps the last ~9,000 lines, so the startup part (where the useful errors are) is gone. Attach the file instead: r2modman → Settings → Browse profile folder → BepInEx\LogOutput.log.

  1. The whole BepInEx/LogOutput.log from the host's r2modman profile — the important part is the top (load + patch lines) and the RepoBots diagnostics block it writes ~3 s after bots join
  2. A screenshot with the F5 overlay open
  3. Your game version, and whether it was the prebuilt DLL or your own build (and any build errors)

License

MIT — see LICENSE. Not affiliated with semiwork. No game code or assets are included.