FluffOS vs Evennia: Choosing a MUD Engine

Evennia and FluffOS can both power text worlds, but they do not ask you to think about the world in the same way. Evennia is a Python/Django application framework for making a MU*. FluffOS is an LPMud driver: an LPC object runtime where rooms, monsters, items, players, commands, daemons, resets, and heartbeats are native ideas. Icesus is a useful comparison point because it is not a toy example. It is a long-running FluffOS world with party combat, guilds, provinces, maps, equipment persistence, and decades of accumulated design.

Short answer: pick Evennia if the deciding factor is Python and modern web-stack familiarity. Pick FluffOS if the deciding factor is the LPMud model: a long-lived world made of runtime objects, inherited room/NPC/item code, driver callbacks, heartbeats, resets, and a mudlib that already knows what a MUD is.

If the real question is "how is Icesus designed?", the answer is not "FluffOS magically gives you Icesus." FluffOS gives the object runtime and the LPC language. Icesus is the mudlib and world built on top: combat rules, party movement, guild progression, maps, provinces, saving rules, commands, administration tools, and content conventions.

The Real Difference

Question FluffOS / LPC Evennia / Python
What is the main unit of game code? An LPC object loaded from a file, often inherited or cloned. Rooms, weapons, NPCs, daemons, and players are all objects. A database-backed typeclass: a Python class layered over Django models such as ObjectDB, AccountDB, ScriptDB, and ChannelDB.
Where does persistence live? Mostly in mudlib conventions: player saves, item saves, daemon saves, and explicit save_object()/restore_object() style storage. In the database by default. Objects have Attributes, Tags, handlers, and typeclass paths stored through Django.
How does time pass? Objects can opt into heart_beat(), use call_out(), react to reset(), or be coordinated by daemon objects. No required global tick. Use Scripts with at_repeat(), utils.delay, or the TickerHandler subscription model.
How much RPG system do you get? The driver gives primitives. A mature mudlib gives the actual RPG. Icesus has spent decades building that layer. The framework gives strong infrastructure, but you usually design the combat, party, guild, economy, and world rules yourself or adapt contrib examples.
Who is it friendliest to? Developers who want LPMud architecture, live object worlds, and content-as-code in LPC. Developers who want Python, Django tooling, web integration, package ecosystem, and familiar deployment patterns.

Objects: Runtime World vs Database World

FluffOS comes from the LPMud tradition where "everything is an object" is not just a design slogan. A room is an object. A sword is an object. A monster is an object. A player body is an interactive object. An area can be a directory of room files. A guild room can be a room object with commands attached by inherited behavior. A daemon can be a singleton object that manages a whole system.

That shapes how Icesus-like code grows. Contributors do not begin by designing database schemas. They usually begin by inheriting local base objects and wiring behavior into the world: room descriptions, exits, NPCs, guild commands, item interactions, reset behavior, and links to larger systems. The driver supplies applies such as create(), init(), reset(), heart_beat(), clean_up(), and master-object hooks. The mudlib decides what those mean for Icesus.

Evennia is object-oriented too, but its object is a database-backed typeclass. Rooms, characters, exits, accounts, channels, and scripts are Python classes layered over Django models. That is powerful, but it changes the mental model. You are often asking "which persistent row is this, what typeclass path does it use, what Attributes and Tags does it have, and what hooks fire when it moves?"

Typical LPC Shape

inherit "/std/room";

void create() {
    ::create();
    set_short("A wind-scoured ridge");
    set_long("Ice cracks underfoot. A narrow trail leads north.");
    add_exit("north", "/areas/frost/rooms/ridge2");
    add_item("ice", "Blue-white and dangerously slick.");
}

void reset() {
    ::reset();
    if (!present("frost sentry")) {
        clone_object("/areas/frost/monsters/frost_sentry")
            ->move(this_object());
    }
}

Typical Evennia Shape

from evennia import DefaultRoom, DefaultExit, create_object

class Room(DefaultRoom):
    def at_object_creation(self):
        self.db.desc = "Ice cracks underfoot."

ridge = create_object(Room, key="A wind-scoured ridge")
ridge.db.desc = "Ice cracks underfoot. A narrow trail leads north."

create_object(
    DefaultExit,
    key="north",
    location=ridge,
    destination=ridge2,
)

The two snippets can produce a similar player experience. They are not the same engineering experience. LPC rooms tend to be source files loaded as live objects. Evennia rooms tend to be database entities whose behavior comes from Python typeclasses. The FluffOS style favors content directories, inheritance, cloning, and driver callbacks. The Evennia style favors ORM-backed persistence, Python imports, settings, handlers, and database queries.

LPC vs Python

LPC is C-like and strange to most modern developers, but it is close to the MUD problem. It has objects, inheritance, arrays, mappings, strings, driver-supplied efuns, and a natural way to say "this thing in the world has code and state." A wizard writing a room, monster, guild trainer, or special item is working directly in the language of the running world.

Python is easier to recruit for. It has mature tooling, test frameworks, packages, editors, type checking options, and a massive developer base. Evennia gets to stand on Django and Twisted. If you want an admin site, a REST API, web character creation, Discord integration, analytics, or a modern deployment story, Python makes those paths feel normal.

The tradeoff is domain distance. In FluffOS, this_object(), environment(), move_object(), present(), clone_object(), call_out(), and set_heart_beat() are old, blunt tools, but they speak MUD fluently. In Evennia, the corresponding work is Pythonic and more explicit: object handlers, move hooks, command sets, Scripts, TickerHandler subscriptions, Attributes, Tags, and Django queries.

Heartbeats, Ticks, and Time

This is one of the deepest engine differences. FluffOS has a built-in heartbeat model. If an object enables its heartbeat, the driver calls heart_beat() periodically. The configured heartbeat is traditionally around a few seconds, although the exact value is local. Objects can also schedule delayed work with call_out(). Rooms and objects can maintain themselves with reset() and clean inactive state with clean_up().

That model fits classic MUD life. Living objects can regenerate, check combat, process poison, follow a target, decay corpses, move NPCs, or update temporary effects. Central daemons can coordinate larger systems. A player-visible hint of this model exists in old Icesus help: if a character's heartbeat gets stuck, players are told to use restorehb.

Evennia deliberately does not require a global MUD tick. Its documentation describes tickers as optional and encourages using the right timing tool for the job: delayed calls, repeating Scripts, or the TickerHandler. The TickerHandler uses a subscription model so many objects can share one timer instead of each owning separate timers. This is modern and efficient, but it means you choose and design your timing architecture instead of inheriting a heartbeat-heavy culture.

Heartbeat-Oriented Combat Loop

void heart_beat() {
    ::heart_beat();

    if (!sizeof(query_attackers())) {
        return;
    }

    accrue_combat_points();
    resolve_defence();
    resolve_weapon_attacks();
    continue_spellcasting();
}

Evennia Script-Oriented Loop

from evennia import DefaultScript

class CombatHandler(DefaultScript):
    def at_script_creation(self):
        self.interval = 2
        self.persistent = True

    def at_repeat(self):
        self.resolve_defence()
        self.resolve_weapon_attacks()
        self.continue_spellcasting()

The Evennia version is not worse. It is clearer about ownership: this Script is the combat handler. The FluffOS version is closer to the old MUD body model: the living object itself wakes up and acts. For a game like Icesus, where combat, regeneration, temporary effects, party state, NPC behavior, and environmental effects have accumulated over decades, the heartbeat-and-daemon style is a natural fit.

Combat Systems

Icesus combat is not a generic "hit monster until dead" loop. Public help describes the RTFM system: Realistic Time Fragment Management. A character divides combat points between attacking, defending, and spellcasting. The player starts with a baseline number of combat points per combat turn, then statistics and skills affect the total. Weapon size, weight, type, strength, and dexterity influence how many offense points are needed to land attacks. Defensive actions consume points. Casting speed depends on points allocated to spellcasting.

That is not just a rules paragraph. It implies a code architecture. A combat round needs to accumulate time fragments, track outstanding attack progress, resolve defenses, continue spellcasting, read weapon and skill data, and let commands such as battle change the allocation. Combat styles and hit styles add another layer: speed, hit chance, damage, dodge, and parry can all be modified by trained style choices.

FluffOS does not give you that complete combat system. Icesus built it. What FluffOS gives is a good substrate for it: living objects, periodic heartbeats, object references, inherited combat code, daemon coordination, and LPC code that can live close to rooms, NPCs, weapons, guilds, skills, and spells.

Evennia gives you infrastructure but not a production RPG combat model. The official tutorials include turn-based and twitch-like examples, and an Evennia combat handler is often a Script associated with a room or fight. That is a clean pattern. You can build a combat handler that stores participants, queued actions, initiative, positions, cooldowns, and temporary effects. You can test it with Python tools. But if your target is Icesus-level combat depth, you are building a lot of game, not merely choosing a framework.

Combat Concern Icesus / FluffOS Fit Evennia Fit
Continuous combat rounds Natural with living-object heartbeats and shared combat code. Use Scripts, TickerHandler, or delayed tasks. More explicit ownership.
Combat-point allocation State can live on the player body and be consumed by inherited combat routines. State can live on Character Attributes or a CombatHandler Script.
Spells continuing during combat Fits the heartbeat model: casting progress advances each combat turn. Fits a Script or task model: casting progress advances when the handler repeats.
Momentums and short reaction windows Can be implemented with temporary state plus call_out() expiry. Can be implemented with delayed tasks, Scripts, or command-state timers.
Testing and external tooling Depends heavily on mudlib tooling and local wizard practices. Python test frameworks, debuggers, type hints, and CI are easier to adopt.

Party Systems and Formation

Icesus parties are not only a chat group or experience split. Public help describes parties as groups that move and fight together, with strong fighters in front taking hits while mages and priests stand behind casting spells. Treasure help also describes personal loot chances per party member and a party-leader bonus based on party size.

That pushes the system beyond a list of names. A party needs membership, leadership, following or group movement, front/back placement, combat targeting rules, loot logic, healing support, and commands for management. It also needs to interact with rooms, exits, combat, death, link loss, and player permissions.

In an LPC mudlib, this often becomes a mixture of player-body state, party daemon, commands added through the mudlib, and hooks in movement/combat code. The engine makes object references cheap and direct: members are objects, rooms are objects, monsters are objects, corpses are objects. The design question is mudlib architecture, not "can the engine represent this?"

In Evennia, a good party implementation might be a persistent Script or a custom Party object with Attributes for members, formation, loot mode, and leader. Movement hooks such as at_pre_move and at_post_move can pull followers along. Combat handlers can read party formation. That is perfectly doable, but it is yours to design. Evennia will not quietly hand you an Icesus-like party ecology.

Guilds, Races, and Character Build Data

Icesus character design is layered: race, background, guilds, profession levels, skills, spells, stats, advancement points, reincarnation, reputation, racial guilds, boons, and long-term training counters. Public help describes guild rooms where players use commands such as join, advance, train, study, list skills, list spells, and cost. It also describes training limits by guild level and stored counters that matter during reincarnation.

That is exactly the kind of system where LPMud history matters. A guild is not just a class definition. It is also a place in the world, a set of commands, a progression table, an economy sink, a social channel, a help file, and a contributor convention. In FluffOS, a guild can be a room and a set of inherited behaviors that update player objects. In Icesus, the accumulated value is the design layer, not just the driver.

Evennia can represent the same concepts cleanly. You might model guild membership as Attributes and Tags, make guild halls as Rooms, add commands through CmdSets, and store progression in Python data structures or database models. Django makes reporting and admin tooling attractive. The cost is initial authorship: unless you import or write a rules package, the guild ecology starts empty.

Rooms, Virtual Rooms, and Maps

Icesus advertises tens of thousands of rooms, and high-level systems such as provinces operate on a larger outworld map. Public province help talks about units moving through outworld rooms, coordinates, waypoints, contacts, detection ranges, autopilot, interception, palisades, battlefields, resources, and ownership. Player towers can be summoned into viable outworld locations. This is a lot of spatial machinery.

FluffOS is comfortable with both file-backed rooms and generated rooms. Classic areas can be directories of LPC room files. Large coordinate spaces can be represented by virtual rooms: paths or coordinates resolve through mudlib/master logic into room objects only when needed. Reset and cleanup behavior let unused objects fall away while important state saves elsewhere. This is a natural way to make a huge text geography without turning every coordinate into a hand-authored permanent file.

Evennia's default room model is database-backed: a Room is an Object with no location, and Exits are one-way objects with destinations. That is excellent for builder-friendly persistence and search. For very large maps, you must choose a map strategy. You can create every room and exit in the database, use coordinates on rooms, use contrib systems such as wilderness or xyzgrid, or build your own map handler that materializes detail as needed. Again, Evennia can do it, but the data model is different.

Spatial Design FluffOS / Icesus-Style Approach Evennia-Style Approach
Hand-authored room area Many LPC files inheriting common room code and linking exits by path. Persistent Room rows, Exit rows, builder commands, or Python world-build scripts.
Generated wilderness Virtual room paths or coordinate handlers can create rooms on demand. Use a wilderness/grid contrib or custom handler instead of naively creating endless rooms.
World map overlays Daemons can map coordinates to terrain, province ownership, encounters, and unit state. Handlers, Scripts, models, Tags, and Attributes can represent terrain, ownership, and dynamic state.
Cleanup clean_up(), resets, destructing transient objects, and explicit saves are idiomatic. Database entities persist until deleted; transient behavior needs explicit non-persistent state or cleanup jobs.

Persistence and Data Storage

FluffOS persistence is explicit and mudlib-shaped. The driver has save_object(), which saves non-static variables of an object to a file if the master object allows it, and restore_object() to read them back. The mudlib decides what objects save, when they save, where they save, and which game rules protect the saved state.

Icesus player help reflects this explicitness. Leaving from an inn can save equipment and return it next login. Quitting elsewhere can drop equipment. Reimbursement help says inventory is safe if saved, and lists lockers and houses as safe storage. It warns that floating discs, holes, the ground, and smiths are not safe places. That is a game design built around explicit persistence boundaries.

Evennia makes persistence feel more automatic. Typeclassed entities live in the database. Attributes can store arbitrary picklable Python data and database-object references. Tags are indexed markers for grouping and searching. Scripts can store global or attached system state and can have timers. This is extremely convenient, especially for admin tools and queries.

The danger in Evennia is that it can become too easy to persist everything. Temporary combat state, cached pathfinding, AI memory, formation snapshots, and UI hints should not all become permanent Attributes by accident. Evennia has non-persistent Attributes for that reason. In FluffOS, the opposite discipline is common: you decide what survives boot, and anything not saved or recreated by reset is gone.

Provinces: Why Engine Choice Is Not Enough

Provinces are a good stress test for shallow engine comparisons. A province system is not just "rooms plus ownership." Icesus province help describes kingdoms, regents, ownership transfer, command codes, resources, manufactured goods, units, palisades, heroes, battlefields, waypoints, autopilot, contacts, interception, detection ranges, allied codes, towers, achievement points, and tradeable magical liquids.

On FluffOS, you would expect that to be distributed across objects and daemons: province command rooms, unit objects or unit-state records, outworld map daemons, resource tickers, war/battle daemons, item objects, save files, logs, and player command handlers. Some pieces are physical room interactions. Some are map overlays. Some are persistent strategy-game state. Some are player economy items.

On Evennia, you could build the same broad design with Django models for province state, Scripts for periodic updates, typeclassed rooms and exits for physical locations, Attributes/Tags for object data, and web admin pages for staff tools. That might be a better fit if you want rich web management, reporting, and database queries. It would not automatically give you Icesus's design. The hard work is the rules, balancing, edge cases, abuse prevention, recovery behavior, and player culture.

What FluffOS Brings to Icesus

For Icesus, FluffOS is not an interchangeable backend. It brings several design commitments that match how the world has grown.

What Evennia Brings Instead

Evennia's strengths are real. It is not "less serious" because it is newer or Pythonic. It simply optimizes for different things.

Where Each Choice Hurts

Pain Point FluffOS Evennia
New contributor onboarding LPC, mudlib conventions, and old MUD architecture are unfamiliar. Python is familiar, but MUD architecture still has to be learned and designed.
Web features Possible, but not the center of the stack. Strong fit because Django is already part of the architecture.
Deep RPG rules Great if the mudlib already has them. Large burden if starting from only the driver. Flexible, but you are likely building core RPG systems yourself.
Large existing world Excellent fit for mature LPMud content and inherited conventions. Migration would be a rewrite of data, behavior, commands, and operations.
Operational clarity Depends on local tooling, wizard practices, save files, and long-lived runtime knowledge. Benefits from familiar database, Python, and web application operations.

So, Should You Build on FluffOS or Evennia?

Pick Evennia if...

Pick FluffOS if...

Why Icesus Stays FluffOS

Icesus is not choosing a stack in 2026 as if it were a weekend prototype. It has been compounding on LPMud/FluffOS ideas since the 1990s. The value is the whole living layer above the driver: guild systems, combat systems, races, backgrounds, reincarnation, maps, outworld rooms, provinces, economy, player storage, help files, wizard workflows, and operational memory.

Porting that to Evennia would not be "switching engines." It would be a long rewrite of code, content, data, assumptions, tools, and edge cases. Even if the end result were good Python, it would have to rediscover decades of Icesus-specific answers. For a new game, Evennia may be the pragmatic choice. For Icesus, FluffOS is continuity: the engine model still matches the shape of the world.

The Contributor Path

If your real itch is not "own a server" but "build meaningful game content," you may not need to start a new MUD. Icesus already has players, history, areas, maps, guilds, and a working production environment. Contributors can help with areas, quests, lore, accessibility, documentation, and eventually trusted wizard work in LPC.

Want to build inside an existing FluffOS world?

Contribute to Icesus

About the Author

Idles is the founder of Icesus, a world he first brought online in 1995. He has a strong background in software development, world building, and hobbyist game design.

Outside Icesus, he has built several successful software companies. He keeps returning to build Icesus because the world is still growing: a long-running place for systems design, storytelling, experimentation, and community.

Sources and Further Reading

Related Pages