Skip to main content

AutoMUD

A persistent telnet/MUD session you drive with small, discrete commands. There is no language model and no API key inside it: the intelligence is whoever runs it, a person, a script, or an autonomous agent. It exists because a raw telnet session is interactive and blocking, so it cannot be held open across separate shell commands. AutoMUD keeps the connection alive in a small background daemon and exposes simple verbs against it.

Install

pipx install git+https://github.com/CharlesCNorton/automud

Or from a clone:

pip install .

Standard library only, Python 3.8+.

Use

automud sites                        # list verified public targets
automud connect achaea               # by name, or: automud connect <host> <port>
automud send 2                       # send a line, print the reply
automud send Maelvorn
automud recv                          # drain any new output
automud wait --for "You are hungry"   # block until output matches a regex
automud state                         # structured game state (GMCP) as JSON
automud status
automud close
verb what it does
connect HOST PORT / --demo NAME open a session and start the daemon (--tls, --encoding ENC, --idle-exit SEC, --debug)
send [TEXT] send one line, print what comes back (omit TEXT for a blank line; --stdin reads the text from stdin)
recv print any new output (--nowait returns whatever is buffered immediately)
wait --for REGEX / --gmcp PKG block until output matches, or a GMCP package updates
gmcp PACKAGE [JSON] send a GMCP message (e.g. Char.Skills.Get)
state [--key PKG] [--times] captured GMCP state as JSON (--times: seconds since each package updated)
status connection, options, vitals summary
log [--tail N] session transcript (last N lines with --tail)
close end the session and stop the daemon
kill force-stop a wedged daemon and clear the session
sites directory of ~45 verified public targets (MUDs, MOOs, BBSes, services)

Every entry in sites was verified reachable by a live probe. Connect to any of them by name: automud connect aardwolf, automud connect telehack, automud connect fics.

Every reading verb takes --json and prints one structured object (data, prompt, connected, elapsed, ...) instead of raw text, which is the natural mode for driving it from a program. A minimal agent loop is just:

automud connect example.com 4000 --json
automud send look --json                 # {"ok": true, "data": "...", "prompt": true, ...}
automud wait --for "^You (win|die)" --max 120 --json

Exit codes: 0 ok, 1 failure, 2 usage error, 3 the operation succeeded but the connection is closed.

Driving it with an agent

There is no agent mode and nothing to configure: an agent drives the same verbs a person does, and everything past that is behavior. One pattern is worth writing down because it falls out of the design. Since the agent holding the session sits between the user and the wire, it can be the user's entire interface to the game and re-voice everything that crosses it: a total conversion of the setting, applied live. The user names the world they want in conversation ("Achaea, but it is Paris on the 14th of July 1789 and I am a hated noble"), and from then on the agent translates both directions, the user's stated intent into real commands and the raw replies into the agreed fiction, mechanics included if the user wants them (vitals re-skinned as a HUD). What keeps it honest:

  • The theme is the user's to pick. If they have not said what they want, ask; do not invent on their behalf.
  • Translate, do not decide. The user's intent picks the command, and the server's actual reply decides what happened. Failures and deaths render in-fiction, but they render.
  • Keep the mapping stable: the same room, denizen, or stat appears under the same converted name every time.
  • out.log keeps the untranslated transcript, so the fiction is always auditable against what the server really said.

Local single-player (Cataclysm)

automud connect cdda launches a local game of Cataclysm: Dark Days Ahead and drives it through the same verbs, so there is a world to play even with no MUD to connect to, an obligate single-player mode for when every public server is finally gone. It is a second backend: a persistent tmux session holds the game open the way the telnet daemon holds a socket, and send / recv / wait / state / status / close all work against it.

Requirements: tmux and a terminal cataclysm binary. On Windows the game runs in WSL and automud bridges to it automatically (AUTOMUD_CDDA_DISTRO selects the distro; AUTOMUD_CDDA_DIR / AUTOMUD_CDDA_BIN / AUTOMUD_CDDA_LAUNCH point at the binary).

automud connect cdda
automud send north              # move; the reply is the message log + a status line
automud send examine east       # a named action, not the seven keystrokes e-x-a-m-i-n-e
automud send nearby             # list items/creatures around you (no map needed)
automud state                   # the character as JSON: stats, hp, needs, place, threats
automud send help               # the action vocabulary for the current screen

The map is obscured on purpose. A blurry ASCII minimap is neither reliable for a language model to parse nor necessary to one that reads a room description, so game-mode output is the message log plus a structured status line (vitals, place, time, nearby threats), never the tilemap. Ask for spatial detail when you want it: send look, send examine <dir>, send nearby.

Actions, not raw keys. send understands word directions (north, se), named keys (enter, escape), and named game actions (examine, pickup, eat, wait, wield, ...) that map to the right key. An unrecognized word is reported, not typed out letter by letter. Single characters are still sent literally, so raw CDDA keys work too.

Character creation is one line per choice. The finicky chargen menus are wrapped:

automud send scenario Sheltered
automud send profession "Sheltered Survivor"    # or: send class ...
automud send stats 8 10 10 10                    # STR DEX INT PER; reports the real values
automud send trait Fleet-Footed
automud send name Dougal
automud send finalize

Each reports what it actually committed (and refuses a locked or mismatched entry rather than silently selecting the wrong one), and in chargen state returns the build so far (scenario, profession, stats, name). The missing-mod prompts a fresh world throws are cleared automatically.

Behaviour

  • Smart waiting. send and recv return as soon as the server stops talking, either a telnet GA/EOR prompt marker or output going quiet, so you never guess a sleep duration. --max caps the wait and --quiet sets the idle threshold. wait extends this to regex/GMCP conditions.
  • GMCP. It negotiates GMCP and parses the structured state modern MUDs push (health, room, exits, skills) into JSON for state. Standard list deltas (Room.AddPlayer, Char.Afflictions.Add, ...) are applied to their lists, and Comm.Channel.Text is kept as a bounded Comm.Channel.History. TTYPE, NAWS and CHARSET negotiation are answered; options it does not implement (compression, MSDP, MXP) are refused rather than mishandled.
  • Encodings and TLS. --encoding sets the wire charset (default utf-8; use latin-1 or cp437 for older servers), and telnet CHARSET negotiation can switch it when the server asks. --tls wraps the connection (--tls-insecure for self-signed certificates).
  • One session per name, held by a background daemon; a new connect replaces it, and -s NAME gives you independent parallel sessions. Session state and transcripts live under a per-user state directory (override with AUTOMUD_DIR); the previous session's transcript is kept as out.prev.log.
  • Robust lifecycle. TCP keepalive is enabled, a dead daemon is detected by pid and its stale session cleared, concurrent connects are serialized by a lock, a wedged daemon is force-killed on reconnect (or by kill), and --idle-exit stops a forgotten daemon.

Security

The control channel is a localhost-only socket authenticated by a per-session random token. State lives in a per-user directory ($XDG_RUNTIME_DIR/automud, else <tempdir>/automud-<uid> on POSIX, %TEMP%\automud on Windows) that is created 0700 and refused if another user owns it. Prefer automud send --stdin for passwords: argv is visible to other local processes, and shell history persists. Plain telnet is cleartext; use --tls where the server offers it.

Tests

python -m unittest discover -s tests -t .

License

MIT. See LICENSE.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

automud-0.3.0.tar.gz (50.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

automud-0.3.0-py3-none-any.whl (43.8 kB view details)

Uploaded Python 3

File details

Details for the file automud-0.3.0.tar.gz.

File metadata

  • Download URL: automud-0.3.0.tar.gz
  • Upload date:
  • Size: 50.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for automud-0.3.0.tar.gz
Algorithm Hash digest
SHA256 61804017771a2f453c7bee6d27ecd46e016d9ed293c4e011259a667c11329465
MD5 e6cf7d011d6d7095341a9ce49db74b8a
BLAKE2b-256 b5b89affebbb7fe68b1d4cdb3ff900ca307aab1f54d0783b69739c894628809e

See more details on using hashes here.

Provenance

The following attestation bundles were made for automud-0.3.0.tar.gz:

Publisher: publish.yml on CharlesCNorton/automud

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file automud-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: automud-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 43.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for automud-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 f7fdd80efb0778fec3ff87d5549d4d26b359e33f12584738ae602a12dfd3caaf
MD5 268fe8446cdc09f8f35f5ae80e062fe3
BLAKE2b-256 2791a8051c20a448e6b85c6aebb45d1a94915e259ae7573426492ea9bf96ee91

See more details on using hashes here.

Provenance

The following attestation bundles were made for automud-0.3.0-py3-none-any.whl:

Publisher: publish.yml on CharlesCNorton/automud

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.3.7

2 files

0.3.6

2 files

0.3.5

2 files

0.3.4

2 files

0.3.3

2 files

0.3.2

2 files

0.3.1

2 files

This release

0.3.0 This release

2 files

0.2.1

2 files

0.2.0

2 files

0.1.3

2 files

0.1.2

2 files

0.1.1

2 files

0.1.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page