Configuration
The framework reads ibf\ibf.toml in the game folder when the game starts. ibf setup
writes it from the default (also shipped as ibf.toml.example). Every key has a default, so
a key you leave out keeps it. A key marked live takes effect when you save the file, with
the game running; the others need the game restarted. A key with a bad value is reported
in the log and keeps its default; a file that is not valid TOML keeps the framework off
until it is fixed.
[host]
| Key | Default | |
|---|---|---|
enabled |
true |
false starts the game without the framework (so does the environment variable IBF_DISABLE=1) |
dev_mode |
false |
developer commands (debug.*, overlay.arrange); a copy of the host is loaded, so it can be rebuilt while the game runs |
command_pipe |
false |
a named pipe that takes console commands from scripts (tools\ibfctl.py) |
[input]
| Key | Default | |
|---|---|---|
bot_pads |
[] (ibf setup: [0, 1]) |
the player slots bots play, from 0: virtual controllers the game sees from its start. ibf match needs pads 0 to n-1 |
script_pads |
[] |
slots the pad.* console commands drive instead; a slot is a bot pad or a script pad |
keep_focus |
true |
the game keeps running when its window loses focus (live) |
minimize |
"run" |
a minimized game keeps playing; "pause" lets it pause as it would (live) |
user_kbmouse |
"focus" |
your keyboard and mouse reach the game only while its window is in focus; "on", "off" (live) |
user_at_start |
"off" |
your keyboard and mouse are held back until the toggle key's first press; "on": from the start |
toggle_key |
"F5" |
the key that lets your keyboard and mouse through, or holds them back |
real |
"allow" |
real controllers: "allow", "block_pads", or "block_all" (also the keyboard and mouse) (live) |
real_pad_map |
{} |
puts a real controller in another slot, e.g. { 0 = 2 }. Once it names a controller, the real controllers it does not name are hidden from the game (live) |
timeout_ms |
250 |
a bot pad that stops being written reads as neutral after this long (live) |
min_press_ticks |
2 |
the shortest press the SDKs make, in ticks (live) |
backend |
"xinput" |
how virtual controllers reach the game; "rawhid" is reserved and not built yet (the XInput backend answers, with a warning in the log) |
[controls] (live)
The pad input each game action becomes: what bots' actions turn into, and what the Navigator presses in menus. Change them if you changed the game's own controls.
| Key | Default |
|---|---|
move |
"left_stick" (or "right_stick", "dpad") |
shoot_up, shoot_down, shoot_left, shoot_right |
"y", "a", "x", "b" |
pause, confirm, back |
"start", "a", "b" |
[mode] (live)
| Key | Default | |
|---|---|---|
run |
"realtime" |
"lockstep": the game waits for every bot pad's answer to each tick (Matches) |
lockstep_timeout_ms |
1000 |
how long it waits for each tick's answers |
lockstep_miss |
"neutral" |
a bot that misses the wait: "neutral" until it catches up, and not waited for meanwhile; "hold": it keeps its last input for that tick only, and the next tick waits for it again (Matches) |
[overlay]
| Key | Default | |
|---|---|---|
enabled |
true |
false: no overlay at all (bots still play and draw nothing) |
scale |
"auto" |
the overlay's size: "auto" follows the window, or 0.5 to 4.0 |
hotkeys |
{ hide = "F4", console = "F2", help = "F1" } |
keys like "F1", "Insert", "Ctrl+Shift+F12" |
[bridge]
enabled = true: the shared memory bots connect to. Off, no bot or tool can connect.
[bridge.tcp]
The bridge over TCP: bots on another machine, on Linux, or in containers of their own
connect to tcp://host:port (C and C++ bots, ibf run --url). Off by default.
| Key | Default | |
|---|---|---|
enabled |
false |
listen |
bind |
"127.0.0.1:47800" |
where: this machine only, or one of its addresses ("0.0.0.0:47800" for all of them) |
token |
"" |
a client that sends it (--token) is a full client: commands, any bot pad, the host's log. An address other than loopback needs one |
Each connection is one more client of the bridge, so it counts against the 8. On loopback
with no token, any program on the machine may connect, as with shared memory. The console's
tcp.allow <token> pad=<n> pins a token to one pad: a bot that connects with it has that
pad bound, and may play it, draw, declare parameters and log, but not run commands, take
another pad or read the host's log. ibf match tcp:<token> and the arena's bot containers
use such tokens (the arena). tcp.allow <token> watch makes a watch token:
a spectator that reads the snapshots and the state and does nothing else (ibf match --watch-token, the arena's observers). tcp.revoke <token> forgets a token and ends its
connection. tcp.token <token> tells, as JSON, a token's kind and pad, whether it is
connected, how many connections it has had, and how the last one ended (goodbye,
closed, silent, protocol, kicked, broken, slow_reader, revoked, host).
tcp shows the listener and its connections. One address may hold 4 connections at a
time.
A full client over TCP runs commands as a local one does, with one difference: the files
its commands write (record.start, state.dump, state.capture, screenshot,
overlay.screenshot, debug.frametrace) go into ibf\remote\ on the game's machine,
named by a relative path (no .., drive or root), so nothing it sends reaches IBF's own
files or anything else on that machine. Their default names (no file given) are the
host's, as for anyone.
[log]
| Key | Default | |
|---|---|---|
level |
"info" |
trace, debug, info, warn, error, off (live) |
json |
false |
also write ibf-*.jsonl |
file_max_mb, file_keep |
20, 10 |
each log's size, and how many are kept |
console_window |
false |
a separate console window with the log |
debugger |
false |
also send the log to an attached debugger (OutputDebugString) |
Logs are in ibf\logs\: ibf-<date>-<time>-<pid>.log for each run, and shim.log.
[state]
| Key | Default | |
|---|---|---|
profile |
"" |
force one profile file (relative to ibf\); empty: chosen by Inversus.exe's SHA-256 (live) |
tick_source |
"auto" |
where ticks come from: "sim_step" (the simulation's step), "present" (each frame) |
[plugins]
[plugins]
enabled = ["hello"] # ibf\plugins\hello.dll
[plugins.hello] # read by the plugin (live)
greeting = "hi"See Plugins.