Create a world, start it, log in.
Install the engine, then ask it for a game. What you get is a directory that belongs to you — the engine is a dependency, not something you copy and edit.
$ pip install megamoo
$ megamoo init mygame
Created /home/you/mygame
212 verb files, a starter world, and an empty game/ packageThat comes from PyPI. The same build is also on the releases page as a wheel, if you would rather pin an exact version or install without reaching PyPI at all.
Requires Python 3.10 or newer, and nothing else: the engine has no third-party dependencies.
Inside mygame:
world.db # the live world — objects, properties, players
verbs/ # the world's code, one file per verb
game/ # your own Python, imported by verbs
megamoo.toml # what to serve, and where
display_screen.txt # the splash players see before the login prompt
README.md # a reminder of the layout
.gitignore # keeps world.db and logs out of git
The starter world it copies in contains the base object library, an
out-of-character lobby, a character generator, one in-character room, and
a wizard account. Those 212 verb files are yours — edit them
freely. The engine keeps no copy you have to merge against, so upgrading
is pip install --upgrade megamoo and nothing you wrote is
touched.
verbs/ and game/ are the source of your
world and belong in git. world.db is running state —
it holds player data and password hashes — and
megamoo init writes a .gitignore that
keeps it out for you.
From inside your game directory:
$ megamoo --dev
Server listening on 0.0.0.0:6770
API server listening on 127.0.0.1:7778Two ports are reported. The first is where players connect. The second is a private door for tooling on your own machine, which is what lets an AI assistant work inside the running world.
You do not choose either number: the server takes the first free port from 6770 for the game and 7778 for the API, and tells you what it got. If you need a specific port — because you have told people where to connect — ask for it, and you will either get that port or a clear error:
$ megamoo --dev --port 6777
Stop a world with Ctrl-C in its terminal, or from inside the game
with @shutdown.
--dev adds
It picks the database in the current directory, switches on the
tooling API with the shared token from
~/.megamoo/token, publishes a discovery file so
tooling can find the running world, and turns on verb auto-reload
so edits to command files land in the running game. For a public
world with real players, name the database instead —
megamoo world.db — the same server with none of those
four.
Two ways in. The browser client needs nothing installed —
megamoo --dev starts it and prints the address:
Play in a browser: http://127.0.0.1:8888/Or connect with any MUD client, or with telnet:
$ telnet localhost 6770The browser client is the quickest way to see your world and the easiest thing to hand somebody else on the same machine. It is the same world either way — the two are just different doors.
Log in as wizard with the password megamoo. You arrive
in the lobby with full authority over the world.
Every copy of the starter world has the same wizard password, and it is
printed in this guide. Use setpass before your world is
reachable by anyone else.
Logging in sends a username and then a password, each as an ordinary line of text. On your own machine that does not matter. Once a world is reachable from anywhere else it does: anyone able to watch the traffic reads the password, and people reuse passwords.
Give the world a second, encrypted port:
$ megamoo world.db --tls-port 6771 --tls-cert cert.pem --tls-key key.pem
Server listening on 0.0.0.0:6770
TLS listening on 0.0.0.0:6771Both ports serve the same world. Which one a player is on changes nothing about the game — TLS sits underneath the connection, and everything above it is identical.
telnet cannot speak TLS, and telnet localhost 6770
is how most people first reach a world — it is the command on this page.
Encrypting the main port would break that for everyone in order to help
the people who already have a client that supports TLS. So the plain
port stays, and the encrypted one is additional. Tell players which to
use; MUD clients that support TLS have a checkbox for it.
A misconfiguration stops the server rather than quietly falling back to plaintext. A port with no certificate, a certificate with no port, a file that is not there, or a TLS port equal to the plain one — each of them refuses to start and says which it was. That is deliberate: the one outcome worth ruling out is a world that looks encrypted and is not.
For a certificate, certbot issues free ones from Let's Encrypt and renews them. They expire every ninety days, so renewal wants to be automatic; the server reads the files at startup, so a renewal takes effect on the next restart.
The web client is served over plain HTTP. If you publish it, put a
TLS-terminating proxy in front — Caddy obtains and renews certificates
on its own. It matters more than it looks: a browser will not open a
ws:// socket from an https:// page, so serving
the page over HTTPS without also terminating TLS for the socket leaves
you with a client that loads and cannot connect.
Each world is a separate process with its own file, so worlds cannot interfere with each other. Running two or three at once is normal practice: the world you care about, a scratch copy for trying things that might go badly, and perhaps last week's backup for comparison.
$ megamoo --dev world.db & # game 6770, API 7778
$ megamoo --dev scratch.db & # game 6771, API 7779
$ megamoo --dev backup.db & # game 6772, API 7780
The same command each time, with nothing to keep track of — each world takes
the next free ports and reports them. Connect to whichever you want by port:
telnet localhost 6771 reaches the scratch copy.
This is what makes copying worlds useful in practice. Testing a risky change
does not mean backing up and restoring. It means copying world.db, running the
copy alongside the original, breaking it freely, and deleting it when you are
done.
With several running it is worth being deliberate. The port you connected to tells you, and so does the world's name in its own terminal. If you are working with an AI assistant, ask it to confirm which world it is pointed at before you let it change anything — "scratch" and "the real one" are one word apart.