← MegaMOO Guide

Getting Started

Create a world, start it, log in.

Creating a world

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/ package
Where to get it

That 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.

What belongs in version control

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.

Starting a world

From inside your game directory:

$ megamoo --dev Server listening on 0.0.0.0:6770 API server listening on 127.0.0.1:7778

Two 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.

What --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.

Logging in

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 6770

The 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.

Change the wizard password immediately

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.

Encrypting connections

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:6771

Both 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.

Why a second port and not the first

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 browser client is a separate question

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.

Running several worlds at once

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.

Which world am I in?

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.