# Playing the bot yourself ./scripts/build.sh # once, and again after any bridge change ./sds.sh play That opens MegaMek — the real one, its own Swing client — with you in one seat and `sds-bot` in the other. Close the window to end the match. ## What it is One container, three processes: - `SdsHost`, running a real MegaMek `Server` with the bot seats attached - `sds-bot`, a child process of that JVM, on the other side - MegaMek's own client, drawing on your X server Everything talks over `127.0.0.1` **inside** the container. Nothing is published, so two of these cannot collide with each other or with a benchmark, and the only thing that leaves the container is the display. ## Picking a scenario and a side ./sds.sh play --scenario scenarios/suite/4v4-jihad-s102040.mms ./sds.sh play --side South `--scenario` takes any `.mms` with exactly two factions; `scenarios/suite/2v2-jihad-s102020.mms` is the default. `--side` takes a faction name from that file's `Factions=` line, and defaults to the first one. The command prints which seat is which before it starts anything: bot : /work/target/release/sds-bot scenario : .../scenarios/suite/2v2-jihad-s102020.mms you : human North opponent : sds South `human North` is also the name to look for in MegaMek's own report and in the unit tooltips, and the name the client connects under. `--bot` puts something else on the other side — the floor bot is `--bot "python3 /work/bots/random_bot.py"` — and the first line always says which one is actually playing. ## What you get afterwards The same files a benchmarked match leaves, in the same place: runs/-play/ .json the result document .report.html MegaMek's round report: rolls, hits, criticals -sds_South.decisions.jsonl every candidate the bot scored -sds_South.weights.json the weights it scored them with .logs/ MegaMek's own scratch for this match So the two readers work on a game you played exactly as they work on a benchmarked one: ./sds.sh explain runs/ --phase FIRING ./sds.sh view runs/ That is the point of playing. A win rate cannot tell you *why* the bot walked into the open; the decision log can, and now you can provoke the situation yourself instead of waiting for it to turn up in a batch. ## There is no lounge A scenario-hosted game does not have one. `ScenarioLoader` hands the server a game that opens on *Initiative Phase for Start of Game Deployment*, so the window appears with the board already drawn and your first deployment turn waiting. Nothing readies you and nothing is synthesised on your behalf: the server simply holds your turn until your client is there to take it, however long MegaMek spent loading its unit cache. The terminal says `server is up` when the client is being started. The cost of no lounge is that the scenario's own force list, skills and camo are what you get; there is no screen on which to change them. Edit the `.mms` if you want different ones. ## Timeouts Every watchdog is off on this path. `--max-rounds`, `--stall-seconds` and the wall clock exist because two bots that stop making progress must not hang a hundred-game batch, and all three are tuned for players that answer in milliseconds. A person deciding a movement phase would trip them. `--play-max-rounds N` puts a round limit back if you want one. The bot's own per-decision budget is unchanged, because it is a budget on the bot and not on the match: it never waits for you. ## X11, and the one-time setup ./sds.sh play --check-display runs `xdpyinfo` in the match image and says whether it can draw on your display. If that works, `play` works. The mechanism is the X11 socket bind-mounted in, `DISPLAY` passed through, and your session's X authority cookie mounted read-only at `/tmp/.sds-xauth`. On this machine — a Wayland session with XWayland — that cookie is the file `XAUTHORITY` points at, and no further setup is needed. Nothing here will run `xhost` for you. If `--check-display` fails it prints the command that would grant access, and running it is yours to decide, because it changes your whole session's X permissions and not just this container's. MegaMek's client settings — window sizes, the game options panel — are kept in `~/.cache/sds-play/mmconf`, seeded from the install's `mmconf/` the first time and left alone afterwards. The MegaMek install itself is not written to, so a game here does not change what a benchmark or a sibling repo sees. ## Container names A play container is named `sdsplay-`, deliberately **not** `sds-*`. `sds clean` kills every `sds-*` container on the machine whoever started it; a benchmark losing that race costs a rerun, and a person losing it costs the game. Your own `play` still kills its container when it exits.