As wonderful as it may be, Python is incredibly slow.
Thus, to make Python worthwhile, we must squeeze as much productivity out of its two main advantages: readability and dynamic typing.
In swampymud, we frequently make use of metaclasses to dynamically add attributes to classes created by developers.
(For example, when creating an equippable Sword class, we may automatically collect certain methods to be used as player commands.)
Every implementation decision is dictated by one priority: make an intuitive, easy-to-use package for people relatively new to Python.
In this engine, characters have an extremely strong sense of class.
A character's class dictates precisely what commands they can use, what items they can pickup, and what locations they can enter.
With this in mind, we made creating a CharacterClass as simple as possible, just derive from character.Character and start writing commands.
Beyond CharacterClasses, the MuddySwamp engine is quite simple. Items can be picked up and added to a character's inventory. Some Items can be equipped. These Equippables give the player access to additional commands whenever they are added.
The world is divided into individual rooms called Locations. Locations contain a description, list of characters in that location, an inventory of items, and a set of entities.
Locations are connected by Exits. You can think of live swampymud world as a directed graph, where Exits are the edges and Locations are the vertices. In a nutshell, this means that Exits are one-way by default.
Entities can be placed inside locations and allow for more player interaction. Like Items, Entities add additional commands to the player's dictionary.
Perhaps best of all, the elements of the world--Locations, Exits, Items, and Entities--can be created and extended dynamically. (Thank you Python!) We encourage users of engine to allow unlimited creation at runtime. You can easily extend these primatives to support things like crafting, location building, spell creation, and more.
swampymud
├── __main__.py
├── mudserver.py
├── location.py
├── character.py
├── entity.py
├── item.py
├── inventory.py
├── mudworld.py
├── mudscript.py
└── util
├── color.py
├── shadowdict.py
├── english.py
├── misc.py
├── biject.py
└── validate.py
- Script executed when
python3 -m swampymud - Handles command-line arguments, loads worldfiles, and starts swampymud server
- Forked from
mudserver.pyfrom Mark Frimston, minimal changes - defines a server class that
- handles events like new players joining
- sends / receives messages
- COMING SOON: a websocket-based server
- defines the
Locationclass- Locations have a proper name and description
- Locations contain characters, entities, and items
- defines the
Exitclass- Exits contain a list of names and a pointer to another location (its destination)
- Exits can also include filters that only permit certain characters to interact with them
- defines
CharacterClass, the metaclass that in-game character classes- "Wizard" would be a
CharacterClass - "Bill the Wizard" is a Wizard
- "Wizard" would be a
- defines
Character, the base class for player-controlled characters- possesses many useful functions for working with characters
- establishes default commands
- developers should derive from Character to create new CharacterClasses
- defines the
Filterclass- filters grant permissions to some characters while denying others
- filters can apply to both individual characters and classes as a whole
- defines the
Commandclass- you can use Command as a decorator to convert a method into a player-accessible command
- you can also apply filters to a Command
- defines
Entity, the base class for all in-game entity-classes- can be placed in Locations much like Characters
- you can use
character.Filterto affect which characters can perceive or interact with a certain entities - Entity methods can be decorator with
character.Commandjust as with CharacterClasses - includes methods
on_enter,on_exit, andon_message, triggers that can be overriden for unique code execution in response to events
- defines
Item, the base class for all Items- you can use
character.Filterto affect which characters can perceive or interact with a certain entities - all item classes include the triggers
on_pickupandon_drop, triggers than can be overriden - if an
on_usemethod is provided, then theItemis consideredUsable
- you can use
- defines
Usable, an abstract class used for convenienceisinstance(item, Usable)returns true if item has anon_usemethod
- defines
Equippable, derived fromItemand used as a base class for all equippable items- include the
on_equipandon_unequiptriggers - support methods decorated with
character.Command(any commands will be made available to the player if equipped) Equippableclasses require a target (seeEquipTargetbelow)
- include the
- defines the
Inventoryclass- used by locations and characters to store items
- essentially serializes and deserializes items when storing them in a dictionary
- future optimizations welcome
- defines the
EquipTargetclass- characters use a dictionary of
EquipTargetkeys to track which items are currently equipped
- characters use a dictionary of
- defines a series of functions for parsing world files
read_worldfileparses a YAML file into a pythonic format, and checks that it has correct sectionsload_preludeloads all the appropriate CharacterClasses, ItemClasses, and EntityClassesload_personaeinitializes all of the serialized objectsload_treetraverses the world tree, adding characters to location, items to inventories, etc.
- defines the
Worldclass to represent an in-game world- stores all Locations in a
dict - tracks the source files for CharacterClasses, ItemClasses, EntityClasses
- provides
to_fileandfrom_filefor saving and loading aWorld
- stores all Locations in a
- provides a method,
World.test_worldwhich loads a test world
- provides a high-level API for
swampymuddevelopers a server instancemessage_allsends a message to all players connected to a running serverimport_locationallows scripts to import a static location when a location is being loaded
- within the
swampymud, we use a handful of methods to make the above functions workexport_servermakes a server available to themudscriptmoduleLocationExportcan be used to make locations available to themudscriptmodule
Module containing miscellaneous utilities.
- has a LOT of documentation and research about ANSI escape codes and terminal color support
- defines the
SGRFunctionabstract base class, which serves as a simple wrapper for coloring text- Implemented SGRFunctions include things like
Italic,Underline,Red,Green, etc. - Wrapped strings can easily work with other strings (formatting, concatenating, and more)
name = Red("Sword") # prints 'Sword' in red print(name) # prints 'Epic Sword' with 'Sword' in red print("Epic " + name) # prints 'Cool Sword' with 'Sword' in red print("Cool {}".format(name))
- Implemented SGRFunctions include things like
- includes several functions for testing
- run
python3 -m swampymud.util.colorto test which formatting options your terminal supports
- run
- includes convenient function
disable_all()that globally disables any color formatting
- defines the
ShadowDictclass- a
ShadowDictfunctions just like normaldict, excepted that old entries are shadowed, not overrwritten:sd = ShadowDict() sd["color"] = "blue" print(sd["color"]) # blue # updating the key with a new item sd["color"] = "red" print(sd["color"]) # red # deleting an item reveals the old one del sd["color"] print(sd["color"]) # blue
- Character commands are stored in a
ShadowDict
- a