(Last updated: March 2006)

There was an old mod for Wolfenstein: Enemy Territory called Omni-Bot, which added computer-controlled bots to fill out the player roster, if you didn't have enough humans for a decent match. I'm not sure if that mod still exists, or still works against more recent versions of ET, since I haven't played in probably a decade. At some point, Omni-Bot got merged into another mod called ETPub, which was nice because that mod included a lot of nice functionality for server operators. I've no idea what the state of that mod is, nowadays, either.

This page details a script that I'd used back in the day to add new Omni-Bot bots to ET using only three keystrokes. It uses a sort-of "menu" system. You hit one key and you get the following keys bound:

  1. Axis menu
  2. Allies menu
  3. Kick all bots
  4. (reset keybindings)
Then each of Axis/Ally will bring up this menu:
  1. Launch a Soldier
  2. Launch a Medic
  3. Launch an Engineer
  4. Launch a Field Op
  5. Launch a Covert Op
  6. (reset keybindings)
So, to launch an allied Field Op, all you'd do is: <key> 2 4. If you forget which number does what, you'll have the handy little menu text on the screen to remind you. PROGRESS!

It'll end up looking like this on your screen:

Note the first: If you use the numbers 1-5 (and zero) for anything other than weapon banks 1-5 (and 10), then you'll have to switch that around in b-menu-reset.

Note the second: Right now at the bottom it just binds all of this to "p," as that was a conveniently unbound key on my machine. Obviously change that to whatever you want (it's certainly not an ideal key for me either - I just haven't decided where to put it).

Note the third: Right now this is set up to happen via "rcon," so if you use this be sure to call "rconpassword <pw>" before you run this, so that it'll work properly. If you want to use this just on your local machine, take out the "rcon" bit.

Anyway, the script (I keep this in botmenu.cfg):

// Bot primitives
set b-menu-axissoldier-p "vstr b-menu-axissoldier-p0"
set b-menu-axismedic-p "vstr b-menu-axismedic-p0"
set b-menu-axisengr-p "vstr b-menu-axisengr-p0"
set b-menu-axisfield-p "vstr b-menu-axisfield-p0"
set b-menu-axiscovert-p "vstr b-menu-axiscovert-p0"
set b-menu-allysoldier-p "vstr b-menu-allysoldier-p0"
set b-menu-allymedic-p "vstr b-menu-allymedic-p0"
set b-menu-allyengr-p "vstr b-menu-allyengr-p0"
set b-menu-allyfield-p "vstr b-menu-allyfield-p0"
set b-menu-allycovert-p "vstr b-menu-allycovert-p0"
set b-menu-kickbots "rcon bot kickall; vstr b-menu-reset"

// Load bot name cycles
exec "botmenu-names.cfg"

// Called from menus
set b-menu-axissoldier "vstr b-menu-axissoldier-p; vstr b-menu-reset"
set b-menu-axismedic "vstr b-menu-axismedic-p; vstr b-menu-reset"
set b-menu-axisengr "vstr b-menu-axisengr-p; vstr b-menu-reset"
set b-menu-axisfield "vstr b-menu-axisfield-p; vstr b-menu-reset"
set b-menu-axiscovert "vstr b-menu-axiscovert-p; vstr b-menu-reset"
set b-menu-allysoldier "vstr b-menu-allysoldier-p; vstr b-menu-reset"
set b-menu-allymedic "vstr b-menu-allymedic-p; vstr b-menu-reset"
set b-menu-allyengr "vstr b-menu-allyengr-p; vstr b-menu-reset"
set b-menu-allyfield "vstr b-menu-allyfield-p; vstr b-menu-reset"
set b-menu-allycovert "vstr b-menu-allycovert-p; vstr b-menu-reset"
set b-menu-kickbots "vstr b-menu-kickbots-p; vstr b-menu-reset"

// Reset keys
set b-menu-reset "bind 1 weaponbank 1; bind 2 weaponbank 2; bind 3 weaponbank 3; bind 4 weaponbank 4; bind 5 weaponbank 5; bind 0 weaponbank 10; echo (done!)"

// Main menu
set b-menu-main "echo ^1[1: Axis]^2[2: Allies]^3[3: Killall]^7[0: Reset]; vstr b-menu-main-a"
set b-menu-main-a "bind 1 vstr b-menu-axis; bind 2 vstr b-menu-ally; bind 3 vstr b-menu-kickbots; bind 0 vstr b-menu-reset"

// Axis menu
set b-menu-axis "echo ^1[1: Soldier]^2[2: Medic]^3[3: Engineer]^4[4: Field]^5[5: Covert]^7[0: Reset]; vstr b-menu-axis-a"
set b-menu-axis-a "bind 1 vstr b-menu-axissoldier; bind 2 vstr b-menu-axismedic; bind 3 vstr b-menu-axisengr; vstr b-menu-axis-a2"
set b-menu-axis-a2 "bind 4 vstr b-menu-axisfield; bind 5 vstr b-menu-axiscovert"

// Allies menu
set b-menu-ally "echo ^1[1: Soldier]^2[2: Medic]^3[3: Engineer]^4[4: Field]^5[5: Covert]^7[0: Reset]; vstr b-menu-ally-a"
set b-menu-ally-a "bind 1 vstr b-menu-allysoldier; bind 2 vstr b-menu-allymedic; bind 3 vstr b-menu-allyengr; vstr b-menu-ally-a2"
set b-menu-ally-a2 "bind 4 vstr b-menu-allyfield; bind 5 vstr b-menu-allycovert"

// Now bind it to a key
bind p vstr b-menu-main
... and I use this script to rotate bot names a bit (if you spawn a bunch of bots without specifying the name, you'll end up with duplicates eventually). I keep this in botmenu-names.cfg:

set b-menu-axissoldier-p0 "rcon bot addbot 1 1 [BOT]Hans; set b-menu-axissoldier-p vstr b-menu-axissoldier-p1"
set b-menu-axissoldier-p1 "rcon bot addbot 1 1 [BOT]Jorg; set b-menu-axissoldier-p vstr b-menu-axissoldier-p2"
set b-menu-axissoldier-p2 "rcon bot addbot 1 1 [BOT]Mathis; set b-menu-axissoldier-p vstr b-menu-axissoldier-p3"
set b-menu-axissoldier-p3 "rcon bot addbot 1 1 [BOT]Wolff; set b-menu-axissoldier-p vstr b-menu-axissoldier-p0"

set b-menu-axismedic-p0 "rcon bot addbot 1 2 [BOT]Claus; set b-menu-axismedic-p vstr b-menu-axismedic-p1"
set b-menu-axismedic-p1 "rcon bot addbot 1 2 [BOT]Wendel; set b-menu-axismedic-p vstr b-menu-axismedic-p2"
set b-menu-axismedic-p2 "rcon bot addbot 1 2 [BOT]Arnolt; set b-menu-axismedic-p vstr b-menu-axismedic-p3"
set b-menu-axismedic-p3 "rcon bot addbot 1 2 [BOT]Sigmund; set b-menu-axismedic-p vstr b-menu-axismedic-p0"

set b-menu-axisengr-p0 "rcon bot addbot 1 3 [BOT]Michel; set b-menu-axisengr-p vstr b-menu-axisengr-p1"
set b-menu-axisengr-p1 "rcon bot addbot 1 3 [BOT]Steffan; set b-menu-axisengr-p vstr b-menu-axisengr-p2"
set b-menu-axisengr-p2 "rcon bot addbot 1 3 [BOT]Ludwig; set b-menu-axisengr-p vstr b-menu-axisengr-p3"
set b-menu-axisengr-p3 "rcon bot addbot 1 3 [BOT]Lucas; set b-menu-axisengr-p vstr b-menu-axisengr-p0"

set b-menu-axisfield-p0 "rcon bot addbot 1 4 [BOT]Heintz; set b-menu-axisfield-p vstr b-menu-axisfield-p1"
set b-menu-axisfield-p1 "rcon bot addbot 1 4 [BOT]Lorentz; set b-menu-axisfield-p vstr b-menu-axisfield-p2"
set b-menu-axisfield-p2 "rcon bot addbot 1 4 [BOT]Dieter; set b-menu-axisfield-p vstr b-menu-axisfield-p3"
set b-menu-axisfield-p3 "rcon bot addbot 1 4 [BOT]Reinhart; set b-menu-axisfield-p vstr b-menu-axisfield-p0"

set b-menu-axiscovert-p0 "rcon bot addbot 1 5 [BOT]Jacob; set b-menu-axiscovert-p vstr b-menu-axiscovert-p1"
set b-menu-axiscovert-p1 "rcon bot addbot 1 5 [BOT]Wilhelm; set b-menu-axiscovert-p vstr b-menu-axiscovert-p2"
set b-menu-axiscovert-p2 "rcon bot addbot 1 5 [BOT]Augustin; set b-menu-axiscovert-p vstr b-menu-axiscovert-p3"
set b-menu-axiscovert-p3 "rcon bot addbot 1 5 [BOT]Rudolf; set b-menu-axiscovert-p vstr b-menu-axiscovert-p0"

set b-menu-allysoldier-p0 "rcon bot addbot 2 1 [BOT]Frank; set b-menu-allysoldier-p vstr b-menu-allysoldier-p1"
set b-menu-allysoldier-p1 "rcon bot addbot 2 1 [BOT]Jed; set b-menu-allysoldier-p vstr b-menu-allysoldier-p2"
set b-menu-allysoldier-p2 "rcon bot addbot 2 1 [BOT]Dwight; set b-menu-allysoldier-p vstr b-menu-allysoldier-p3"
set b-menu-allysoldier-p3 "rcon bot addbot 2 1 [BOT]Mac; set b-menu-allysoldier-p vstr b-menu-allysoldier-p0"

set b-menu-allymedic-p0 "rcon bot addbot 2 2 [BOT]Tim; set b-menu-allymedic-p vstr b-menu-allymedic-p1"
set b-menu-allymedic-p1 "rcon bot addbot 2 2 [BOT]Brandon; set b-menu-allymedic-p vstr b-menu-allymedic-p2"
set b-menu-allymedic-p2 "rcon bot addbot 2 2 [BOT]Hugh; set b-menu-allymedic-p vstr b-menu-allymedic-p3"
set b-menu-allymedic-p3 "rcon bot addbot 2 2 [BOT]Adam; set b-menu-allymedic-p vstr b-menu-allymedic-p0"

set b-menu-allyengr-p0 "rcon bot addbot 2 3 [BOT]George; set b-menu-allyengr-p vstr b-menu-allyengr-p1"
set b-menu-allyengr-p1 "rcon bot addbot 2 3 [BOT]Clark; set b-menu-allyengr-p vstr b-menu-allyengr-p2"
set b-menu-allyengr-p2 "rcon bot addbot 2 3 [BOT]Gordon; set b-menu-allyengr-p vstr b-menu-allyengr-p3"
set b-menu-allyengr-p3 "rcon bot addbot 2 3 [BOT]Darrin; set b-menu-allyengr-p vstr b-menu-allyengr-p0"

set b-menu-allyfield-p0 "rcon bot addbot 2 4 [BOT]Drake; set b-menu-allyfield-p vstr b-menu-allyfield-p1"
set b-menu-allyfield-p1 "rcon bot addbot 2 4 [BOT]Cole; set b-menu-allyfield-p vstr b-menu-allyfield-p2"
set b-menu-allyfield-p2 "rcon bot addbot 2 4 [BOT]Scott; set b-menu-allyfield-p vstr b-menu-allyfield-p3"
set b-menu-allyfield-p3 "rcon bot addbot 2 4 [BOT]Peter; set b-menu-allyfield-p vstr b-menu-allyfield-p0"

set b-menu-allycovert-p0 "rcon bot addbot 2 5 [BOT]Blake; set b-menu-allycovert-p vstr b-menu-allycovert-p1"
set b-menu-allycovert-p1 "rcon bot addbot 2 5 [BOT]James; set b-menu-allycovert-p vstr b-menu-allycovert-p2"
set b-menu-allycovert-p2 "rcon bot addbot 2 5 [BOT]Neil; set b-menu-allycovert-p vstr b-menu-allycovert-p3"
set b-menu-allycovert-p3 "rcon bot addbot 2 5 [BOT]Brent; set b-menu-allycovert-p vstr b-menu-allycovert-p0"

Problems
  1. By default, ET seems to limit the rate of incoming messages (via echo) to one per second. This means that you can actually launch bots before the initial menu even shows up. It's a bit annoying because you'll have three echos for the menu (the initial menu, the specific team menu, and then the "done" message to tell you that your keybindings are back to normal), plus however many messages for the actual bot joining (up to three it appears). So basically you've tied up your message queue for six seconds with each bot.

    This is easily solvable (apparently) in ETPro because they have the cvar b_popupTime (and some other, related cvars) which regulates how often messages are allowed to pop up. I'd like to be able to set that down to 0 for the duration of the script and then bump it back up to the default. For now, though, I don't think that such a cvar is available to Omni-Bot/ETPub. Hopefully that's something that can make its way into ETPub, which would then find its way into Omni-Bot. I seem to have found the ETPub source, so I was going to look at what's necessary to do this.

  2. Not so much a problem per se, but it's a limitation. If you want to kick just one bot by name, right now you've got to just run the whole command by hand. I don't know of any way of accepting arguments to shorten stuff up.