Announcing mooR 1.0-beta1

In the fall of 2022, frustrated by the State Of the Internet (and annoyed at 25 years of my own procrastination), I thought “it can’t be that hard” to modernize LambdaMOO — an early-90s multiplayer/multiuser, text-based shared world server that pioneered persistent, programmable social spaces.

But what started as a weekend-or-two experiment between jobs, evolved into a multi-year journey to build a technology layer for reinventing online interaction: one that prioritizes user agency over walled gardens, and encourages people to create, not passively consume.

mooR is a network-accessible, multi-user, programmable system for building online social environments, games, and collaborative spaces. It’s my reconstruction (complete rewrite and then some) of the underlying technology that powered LambdaMOO, built from the ground up with contemporary technology and techniques (while still maintaining full backwards compatibility with existing LambdaMOO databases).

My vision is to take what was once an arcane, retro artifact from the past and transform it into a platform people can actually use and extend today. Not as a retro-computing museum exhibit, but as a foundation for building the kinds of participatory, hackable, community-driven spaces that today’s online world has largely abandoned.

After three years of development, mooR version output showing 1.0.0-beta1+ec9f4a2 in which this software has basically eaten my whole life for a time… I’m excited to announce the first beta release: mooR 1.0-beta1. This is a major milestone which means:

  • Feature freeze - The gate closes (for a time) on new non-critical feature additions and the instability they might bring. Our focus shifts to bug fixes and stability.
  • First official release artifacts - Tagged Docker images and Debian binary packages become available.
  • Production focus - All critical 1.0 features are complete and work on mooR shifts (for a time) to support external users, working on my own “cowbell” core and a fun MOO that uses it, and ironing out production problems and bugs for any of the above.

A note on audience: This post is written for a mostly technical audience—people who might have an interest in mooR or MOOs or MUDs or dynamic languages or whatever generally. But my vision for the audience for things built with mooR is much broader. The overarching goal of mooR is to be a software platform for building user-friendly, fun spaces. To create, in modern, sophisticated form, what I first encountered on LambaMOO in the early 90s: A vibrant community whose technical abilities ranged from beginner to expert, all of them collaboratively developing the software that defined their community experience.

(But for the nerds: a MOO is like a multiuser Smalltalk — everything is an object, everything is inspectable and modifiable at runtime, and the development environment is inside the running system. Or think of it as a database you can “play” in — where the schema, the code, and the data are all first-class objects that users can examine, extend, and remix while others are connected. Or perhaps MUD meets Jupyter notebook — a persistent shared world where the REPL is collaborative and the state never goes away.)

Also, alongside the mooR engine itself, I’ve also been building Cowbell – a from-scratch MOO core* for mooR that reimagines what a MOO foundation should look like for 2025. While mooR provides the infrastructure (objects, transactions, networking, security), Cowbell provides the social programmability layer (structured events, perspective rendering, rich content, social features) designed to be competitive with contemporary social platforms like Discord or Slack while preserving MOO’s hackable nature. More on that below.

(* A MOO core is a starter database for a MOO. In the MOO context “the database” refers to the user-editable code and data. A MOO core database provides a foundation of objects, libraries and related tools for further development.)

But first… support the project

mooR has been a labor of love (and obsession) for the past three years. It’s a compiler, a virtual machine, a database, and a network server all rolled up into one, and it’s complicated and huge. I’ve invested a lot of time, especially for the last few months when I haven’t been working a day job and have been working on it (more than) full time. It’s free and open source software, and will remain so… But… if you find value in this work—whether you’re building with mooR, excited about its potential, or just appreciate seeing ambitious open source projects come to life – consider supporting its continued development.

You can do by sponsoring me on GitHub Sponsors. There’s also an active Discord community where we discuss development and share ideas.

Your support helps me:

  • Dedicate time to maintenance, bug fixes, and responding to user issues
  • Continue development on mooR and associated projects
  • Keep the demo server running and accessible
  • Create documentation, tutorials, and examples
  • Work on future enhancements beyond 1.0

Every contribution—whether one-time or recurring—makes a difference and helps ensure mooR remains actively maintained.

What’s New Since October 2024

The last development update covered work through early October 2024. Since then, we’ve completed all the critical pieces needed for a 1.0 release. Here’s what landed in the final sprints.


1. Our web client, and its built-in development environment

mooR ships with its own web-based interface that the user can use to connect and use the MOO environment from their web browser or from a mobile device. It communicates through REST & WebSocket APIs to the mooR backend, and provides richer interactions than you’re probably expecting…

Login screen

Try it yourself at our development server: https://moo.timbran.org

Web client interface

An “IDE” Experience For Programmers

Over the last two months the web client has evolved into a full-featured development environment, allowing users with “prog-bits” (programmer permissions) to author rich persistent objects and their behaviours in the world using modern syntax highlighting, autocompleting editor facilities and a powerful object browser / inspector / manipulation UI.

  • Verb Editor: Monaco-based editor (the same engine powering VS Code) with full MOO syntax highlighting, intelligent autocompletion for builtins/properties/verbs minimap, word wrap toggles.

Verb editor

  • Object Browser: Classic Smalltalk-style 3-pane browser for interactive exploration of the object hierarchy with property & verb management, object creation/recycling, inline verb and property editing, and direct export of objects to files for backup.

Object browser

  • Structured Property Editor: An editor for lists, numbers, or arbitrary MOO literals.

Property editor

  • Structured Error Display: Compile errors presented inline with proper source locations and helpful diagnostics

Richer UI Components

In conjunction with Cowbell (or your own core, with the right modifications) the web-client has niceties like profile pictures / thumbnails, inline images, formatted tables, italicized / underlined text, style hints on events, syntax highlighted code listings, etc, along with extensions to the read() builtin to allow:

  • Dynamic prompts with buttons and confirmation dialogs (which Cowbell uses for its in-world LLM coding & building agents…)

Dynamic prompts

  • Text areas for multiline input
  • Form-style interfaces for complex data entry

Usability Improvements

  • Better UI consistency & styling throughout
  • Improved accessibility hints and keyboard navigation with proper tabbing
  • Reorganized menus and settings for better discoverability
  • More robust login with OAuth2 support and reconnection handling

2. Production Deployment Examples

mooR itself is more complicated than a classic MUD server to run because it’s broken up into a modular multiple process architecture, and there’s a web services piece, and a single-page-application written in React, and, well, all that requires a bit of glue to get it all orchestrated with encryption keys, and configuration files, and SSL certs, and so on…

Getting mooR into production was previously a bit more DIY. But the new deploy/ directory content provides some example, almost turnkey solutions which you can start from for getting up and running.

Ready-to-Use Configurations

  • Docker Compose Examples:

    • telnet-only - Minimal setup for classic telnet access
    • web-basic - Web client without SSL for local/dev environments
    • web-ssl - Production-ready with HTTPS and reverse proxy. You’ll have to roll your own certificate renewal.
  • Kubernetes Setup: Manifests for cloud deployment with volume management and service configuration & a test script which exercised them using kind

  • Nginx Examples: Reverse proxy configurations for various deployment topologies

  • Automated Testing: test-all.sh validates all deployment configurations using Incus containers, ensuring examples stay working

Official Packages

First time ever: Official release artifacts are available!

  • Docker Images: Tagged images for moor-daemon, telnet-host, and web-host
  • Debian Packages: Available for moor-daemon, moor-emh, moorc, telnet-host, and web-host
  • Version Flags: All binaries report version information for diagnostics

These improvements hopefully make mooR accessible to operators without deep Rust or systems knowledge.


3. Secure RPC Communications

As mentioned above, mooR has a modular multiprocess architecture.

Each of those processes talk to each other using ZeroMQ, either over IPC or TCP connections. This flexibility allows system administrators to place the pieces that are network accessible – either inbound via telnet or http or output services (like the “curl-worker” which can allow communication with outside web services from inside the MOO) elsewhere in their data centre or even across the world from the “daemon” (the database and MOO runtime itself).

For most people, this complication won’t be needed, and they can simply use the default provided IPC configuration on a single host, and forget about it.

But for clustered configurations … the communication layer has been reworked significantly over the past month.

Previously we used a custom authorization layer based around PASETO tokens, and there was no encryption over the TCP sockets themselves.

Instead this has been replaced with ZeroMQ’s standard way of doing encryption and authorization – “CURVE” – which gives you:

  • Elliptic curve cryptography (Curve25519) for all RPC communications. This means that everything from the MOO to the web client and back is now fully encrypted.
  • Automatic key generation and management
  • Mutual authentication between components
  • Protection against MITM attacks in multi-host deployments

This also came with work that added:

  • XDG-compliant config paths (~/.config/moor/) for a more standard configuration story (thanks for the suggestion, Norm!)
  • rotate_enrollment_token() builtin for runtime key rotation from within the MOO environment itself.

Our Docker configurations give examples of how to mount the volumes for the configuration pieces and how to glue enrollment together.


4. End-to-End Encrypted Event Log

mooR has an optional “event log” which provides a Discord/Slack-style “infinite scrollback” in the web client, by recording all player interactions for history/replay. This lets you see things that have happened while you weren’t online, and to go back through and see the past from when you were.

Event log

However with this event log being stored on the server, this raised obvious security and privacy concerns. And it also struck me that if people are going to be hosting public mooR instances, they’re going to have to be compliant with regulations like the GDPR in the EU, or the PIPEDA here in Canada.

So I made a major effort this past month to provide end-to-end encryption and tools for users to manage that log.

Client-Side Encryption

Event logs are now fully encrypted end-to-end:

  • All entries encrypted client-side before storage on the server. Nobody can decrypt that log but you, and you need the key / password to do so.
  • Uses modern encryption (X25519/ChaCha20-Poly1305 via the age format).
  • Encryption is end-to-end: the server never sees plaintext content - only encrypted blobs.
  • Encryption keys are derived from user passwords or stored in browser localStorage for longer-term storage.

Privacy Protection

  • Server administrators cannot read event logs.
  • Stolen event log backups contain only encrypted data.
  • Each user controls their own encryption password (separate from MOO login).
  • Encryption is mandatory - events cannot be logged without it.

Management Features

  • Builtins for managing event log: retrieval, deletion, status queries.
  • Our web client has tools to download your complete encrypted history for offline archival, or purge it forever.

Event log management

  • It’s optional: event log can be completely disabled, e.g. for telnet-only deployments or for people who don’t want the feature or the associated storage costs. And the client gracefully detects this and won’t bug you about it, if the administrator has it turned off.

5. Emergency Admin Tool (moor-emh)

LambdaMOO included an “emergency mode” for database recovery when administrators got locked out.

mooR’s new Emergency Medical Hologram (moor-emh) is a standalone binary that goes quite a bit further.

Emergency Medical Hologram

Here are some of the things it can do…

  • Direct Database Access: Bypasses normal authentication.
  • User Switching: su command to assume any player’s identity for debugging.
  • Object Inspection: View and modify any object, property, or verb without permission checks.
  • Object Import/Export: Load objdef files directly for recovery scenarios.

Which you can use to…

  • Recover from accidental permission changes that lock out wizards.
  • Monkey-patch when core objects are corrupted, or you need to selectively upgrade.
  • Database migrations and bulk object manipulation when binary formats change.
  • Debug situations.

6. Better Compile Error Diagnostics

Many MOO programmers are relative novices in software development or if they are more professional software engineers, they’re unfamiliar with the MOO language’s quirks. Previously, mooR’s compiler errors were as, or even slightly more arcane and unhelpful as LambdaMOO’s.

This past month compile error reporting has been completely overhauled to provide better diagnostics:

  • Context snippets showing exactly where problems occurred.
  • Helpful suggestions for common mistakes (e.g., “did you mean endif instead of end if?”).
  • ANSI coloring and graphical indicators in supported environments.
  • New format_compile_error() builtin returns structured error data for in-MOO tooling.
  • Web verb editor displays errors inline with red squiggles.
  • Textdump/objdef imports report specific line numbers and objects on failure.
  • Better diagnostics for type errors, constant assignments, and scope issues.

7. Expanded Built-in Functions

mooR has a substantial collection of new “builtins” (built in utility functions for MOO programmers) that fill in some gaps in the original LambdaMOO builtin function API, and add some things I and others found useful while developing cowbell and other projects. These are documented in the mooR book.

Here are just the ones that were added in the last month:

Cryptography additions

  • age_passphrase_encrypt() / age_passphrase_decrypt(): Password-based encryption using the age specification (Thanks Blake!).
  • paseto_make_local() / paseto_verify_local(): PASETO v4 tokens for authentication applications inside MOO.
  • binary_hash(): Cryptographic hashing for binary data. (We only hashed strings previously.)

Command Parsing

  • parse_command(), find_command_verb(), dispatch_command_verb(): Expose internals of the command parser for customizability while keeping parse efficiency. Using these functions, it’s possible to extend your command parser to more complicated commands and interactions, as I’ve done in Cowbell.
  • prepositions(): Returns a list of all the valid prepositions possible with the command parser. (MOOs in the past would hardcode these and their numeric IDs into their database.)

Utility Functions

  • uuid(): Generate UUID v7 strings with timestamp ordering.
  • sort(), reverse(), explode(): Were documented but never implemented in classic LambdaMOO.
  • function_help(): Structured help from Rust docstrings for in-MOO documentation (Thanks, Blake!).
  • suspend_if_needed(): More efficient version of the common LambdaCore pattern.

System Management

  • objects(): Return all objects (necessary with UUID and anonymous objects).
  • flush_caches(): Manual cache flushing for benchmarking.
  • rotate_enrollment_token(): RPC enrollment management.

Binary Data

  • binary_to_str() / str_to_binary(): UTF-8 conversions.
  • Improved binary type support throughout

8. Performance & Reliability

Finally, I spend time every month yak-shaving on performance, because that’s the kind of nerd I am. And as I’ve been now running mooR on a public (though not well-used) instance, as have others, I have been ironing out reliability issues as they arose.

In terms of optimizations..

  • Optimized verb and property cache flush operations, to be less pessimistic, and a little smarter. This should yield some modest improvements in code execution speed.
  • Improved anonymous object garbage collection for people who have that feature turned on.
  • Overall scheduler task queue optimizations, reducing latency.
  • Some better statistics reporting for identifying bottlenecks.
  • Reduced CPU usage overall by hammering away finding places where we were busy-looping too much, or just doing stupid things.

More Transactional Consistency Checking

mooR is built around my custom in-memory MVCC object database with a serializable isolation model. It’s complicated and neat. I already had in place various tests for verifying consistency, but this month I put more work into getting those into the automated CI process, and making them more robust.

  • We use “elle” (from Jepsen) for consistency checking, but were only doing a simple list-append test, and so I also added its “rw-register” consistency checker and verified that mooR behaved properly with it.
  • In the process caught and fixed several subtle concurrency bugs.
  • Got the above into our CI workflow on codeberg.

Quality of Life

Finally, there were bug fixes and general quality of life things:

  • Some bug fixes to command parsing, object matching, telnet handling.
  • Better logging with reduced spam and more actionable error messages.
  • Documentation improvements throughout the manual.

What’s Next

We’re now in the…

Beta Period

The beta1 release marks a feature freeze. From now until 1.0:

  • Bug fixes only - No new features.
  • Stability focus - Testing, hardening, edge cases.
  • Documentation - Filling gaps, improving examples.
  • Performance tuning - Profiling and optimization.

This will start on-or-just-after November 18th in the form of a 1.0 release git branch, and a tag for beta1, along with formally built official binary artifacts.

How to Help

  • Deploy it: Try the deployment examples, report issues
  • Break it: Look for edge cases, race conditions, crashes
  • Document it: File bugs, suggest documentation improvements
  • Build with it: Create MOOs, stress test the system

Join the Discord community to discuss development, share ideas, and get help from other developers and users!

Getting Started?

Try the demo: https://moo.timbran.org

Download from the official release page:

  • Docker images (x86_64 and aarch64): codeberg.org/timbran/moor:1.0.0-beta1-x86_64 (or use :latest). See the deployment examples for ready-to-use Docker Compose configurations.
  • Debian packages: Available in the Codeberg Debian repository or as individual .deb downloads for amd64 and arm64
  • Source code: ZIP and TAR.GZ archives available for download or build from source with git tag 1.0.0-beta1

Documentation: timbran.codeberg.page/moor-book-html

Deployment examples: Check out the deploy/ directory for ready-to-use Docker Compose, Kubernetes, and Nginx configurations that you can use to get up and running.


Looking Forward

mooR has come a long way from the initial commit three years ago. What started as a bit of a frustrated old-man-yells-at-cloud experiment (followed by 3 years of yak shaving) has turned into a rather large and all-encompassing project that ate most of my life.

But actually the real work begins now, but it’s not really my job, it’s yours: building compelling worlds that demonstrate why MOO still matters in the second half of the 2020s.

Cowbell; a fresh foundation for new projects

The technical foundation is ready, but there’s another piece I’ve been building alongside mooR: Cowbell – a from-scratch MOO core database designed for contemporary social interaction.

While mooR supports downward compatibility with LambdaMOO, mooR also supports more modern capabilities that LambdaCore (the MOO core that LambdaMOO and almost all running MOOs use) simply cannot make use of. Cowbell is a core designed to support using those capabilities.

  • Original LambdaMOO supported only one event type: simple strings. Cowbell supports structured narrative events with metadata and perspective rendering – show different text to different viewers based on context, or client capability.
  • Rich content first-class: HTML, markdown, and structured data natively supported.
  • Capability-based security: Fine-grained permissions that can be delegated beyond simple ownership models.
  • Modern auth: argon2 hashing, multi-connection support per player.
  • Web-first design: Built to eventually compete with Discord, Slack, and contemporary messaging platforms while preserving MOO’s creative character.
  • ”AI” agents: Not to be left out from any wave of hype, Cowbell includes facilities for talking to external LLMs ($llm_client), a framework for building in-world agents ($llm_agent), a coding agent (“Data Visor”), an interactive world building assistant (“architect’s compass”), and an example interactive chat bot (“Mr.Welcome”)

Cowbell leverages all the new features in mooR – structured events, rich prompts, images, encryption, mooR’s newer language syntax features and datatypes – to provide you with a foundation for creating messaging platforms that are actually feature-competitive with modern platforms like Discord, Slack, etc. But it’s also designed to be composable: you can use parts of it, extend it, or build something completely different.

The “Killer App” Challenge

Now we need the “killer app”—the world that shows newcomers what makes MOO special: persistent, programmable, shared spaces where everything is hackable and social interaction is the point.

Maybe it’s:

  • A collaborative fiction writing space that captures Discord’s ease of use with MOO’s persistence.
  • A learning environment where programming is social and the system teaches itself.
  • A hybrid game/chat space that blurs the line between playing and building.
  • A role playing MUD that integrates both graphics and text.
  • A fully graphical RPG with a custom client that uses mooR as its coordinating backend and development environment.
  • Something entirely new that we haven’t imagined yet.

If you’re reading this and thinking “I have an idea for a world…”, this is your moment.

The engine is ready. Cowbell provides a reasonable starting point. Ask me for help.

Let’s build something amazing.


Acknowledgments

This last month’s work wouldn’t have progressed without the contributions from (but not exclusively from):

  • Blake Oliver: Age encryption builtins, function_help, testing and feedback
  • Robert Pate II: Extensive testing and bug reports
  • Steven Owens: Documentation and book edits / suggestions
  • ”Rune”: Testing and feedback while developing his own MOO on top of mooR.
  • ”Pythongirl”: Feedback and ideas sounding board
  • Norman Nunley Jr: Ongoing support and ideas for many years.

Thank you to everyone who believes in the vision of making MOO accessible again.


mooR is open source and available at codeberg.org/timbran/moor. Documentation is at timbran.codeberg.page/moor-book-html.

← Back to Blog