One of the primary goals for mudpy is to apply a consistent data model for all information, from configuration and preferences to user accounts and world data. Individual pieces of information are called facets, and are grouped together into entities called elements. Elements are meant to be treated as loosely-typed objects (if it walks like a duck and talks like a duck…), while facets within them have predefined names and are strictly typed. This combination provides the ability to have facet inheritance among elements as a layered sieve.

The mudpy data model consists of a mix of persistent data (stored externally but cached in memory), and ephemeral data (cross-reference indexes which can be regenerated from it). For now, persistent data is stored externally in a tree-like hierarchy of text files starting from a main configuration usually named mudpy.conf and cached in memory as a single python dict known as the universe. This default implementation, while memory-hungry, is planned so as to reduce the number of dict lookup operations performed to retrieve an individual piece of information, when compared with the nested dict model used previously.

The universe is organized with a layered namespace using the period (.) symbol as a separator. It is rooted at “.” and grows to the right with successive nodes. The right-most node must always be a facet, and the remainder of the series thus denotes the absolute name of an element within the universe (the second node from the right being the relative element name and the remaining nodes to the left are called the group). Near the root of the universal namespace are a number of special elements anchored within the .mudpy branch which provide necessary configuration information and keeps some basic elements from cluttering the rest of the tree:
Where new actor elements with no specified storage destination are kept by default.

Where the default archetype definitions are grouped together.

Where the default command definitions are grouped together.
Defines default long-term storage locations for various element groups.

Defines default values and validation checks for every facet.

Defines filesystem-based backend storage meta data.

Language specific configuration.

Various aspects determining mudpy performance.

Configuration for logging.
Where the default menu definitions are grouped together.

Defines movement directions.
Network socket configuration.

Process-specific configuration.

Where new prop elements with no specified storage destination are kept by default.
Where new room elements with no specified storage destination are kept by default.

Timing-specific settings and scheduling for the main loop.

Long-term storage is accomplished with a trivial format, using line terminators to separate arbitrarily-ordered records. The one major drawback to this format is that multi-line formatting of a single string value is impossible, though workarounds are provided through the $(eol) and $(inc:filename) replacement macros. Each record consists of a key and a value separated by an equal sign (=), where the key can be either absolute (beginning with a “.” character) or relative to the anchor specified by the parent file which loaded it. Special records can also exist to describe a data file’s properties, and always begin with an exclamation mark (!). These are stored in the universe under the .mudpy.file group with elements named for escaped versions of the file path (. and : replaced by \. and \:) and the exclamation mark stripped from the beginning of each facet.

Arbitrary string providing information about the file (commentary, copyright, et cetera).

List of additional data sources to load and where to anchor their elements in the universe. The value is prefaced by the storage medium separated from the remainder by an optional parenthetical parameter and a colon. The only type implemented so far is file and the optional parameter is p to indicate a private file which should only be readable by the account under which the process is running rather than created with the default umask (ignored on unsupported platforms).

Boolean value indicating read-only status.

Lines begining with a pound symbol (#), with or without whitespace indentation, are ignored by the data loader and can be used to manually disable records or add comments. Empty lines or lines containing only whitespace are also ignored and can be used to separate groups of records if desired. The remaining lines are split at the first =, then independently stripped of any leading or trailing whitespace (so you can indent or tabulate records as you like). The left half of each becomes a unique key in the universe, and the right half is run through the eval() function before being assigned to that key in the dict. One side effect of the eval() function is that you can place comments at the ends of lines as long as you separate them from the value with a #, and they will be correctly ignored by the parser.

Note that any file not protected with a !lock record will be regenerated and rewritten by mudpy if its records are changed, so record format will be normalized and records reordered alphabetically. Extraneous whitespace (indentation/tabulation), trailing commentary, and any empty lines or lines beginning with # will be lost in this process as well. (This may be fixed at a later date.)

Leave a Reply

You must be logged in to post a comment.