{"id":18412278,"url":"https://github.com/bashrc2/abermush","last_synced_at":"2025-04-07T11:31:58.546Z","repository":{"id":52525540,"uuid":"277362487","full_name":"bashrc2/AberMUSH","owner":"bashrc2","description":"AberMUSH is a text based role playing game with UTF-8 ANSI graphics, set in the AberMUD 5 universe. Explore, battle and adventure in a fantasy version of medieval Wales. Experience DnD style combat, gambling disputes, excessive ale consumption and puzzling mysteries in the once magnificent but now fallen city of Tranoch, with dynamic scenery, tides, wildlife and weather effects.","archived":false,"fork":false,"pushed_at":"2025-04-03T22:21:36.000Z","size":40188,"stargazers_count":23,"open_issues_count":1,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-03T23:25:04.284Z","etag":null,"topics":["aberystwyth","ansi-art","fantasy","game","mud","mud-game-server","multi-user-dungeon","mush","rpg","telnet","terminal-graphics"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bashrc2.png","metadata":{"files":{"readme":"README.md","changelog":"history.py","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-07-05T18:41:13.000Z","updated_at":"2025-04-03T22:21:44.000Z","dependencies_parsed_at":"2025-04-03T23:32:34.173Z","dependency_job_id":null,"html_url":"https://github.com/bashrc2/AberMUSH","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bashrc2%2FAberMUSH","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bashrc2%2FAberMUSH/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bashrc2%2FAberMUSH/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bashrc2%2FAberMUSH/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bashrc2","download_url":"https://codeload.github.com/bashrc2/AberMUSH/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247644305,"owners_count":20972266,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aberystwyth","ansi-art","fantasy","game","mud","mud-game-server","multi-user-dungeon","mush","rpg","telnet","terminal-graphics"],"created_at":"2024-11-06T03:40:49.328Z","updated_at":"2025-04-07T11:31:53.537Z","avatar_url":"https://github.com/bashrc2.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"![AberMUSH](docs/title.png)\n\n\u003cblockquote\u003e\"Once a year the dragon emerged from its cave. The people of the valleys could hear its thundering roar as it awakened from its long slumber.\"\u003c/blockquote\u003e\n\nAberMUSH is a text based role playing game with UTF-8 ANSI graphics, set in the [AberMUD](http://ftp.linux.org.uk/pub/linux/alan/Software/Games/AberMUD5/SOURCE/) 5 universe. Explore, battle and adventure in a fantasy version of medieval Wales. Experience DnD style combat, gambling disputes, excessive ale consumption and puzzling mysteries in the once magnificent but now fallen city of Tranoch, with dynamic scenery, tides, wildlife and weather effects.\n\nThis game includes 8 bit console graphics, but if you are a MUD purist or don't need graphics then you can turn them off.\n\nBased on dumserver by Bartek Radwanski and Mark Frimston https://github.com/wowpin/dumserver\n\n![AberMUSH](docs/screenshot2.jpg)\n\nYou can also use a mud client of your choice if you wish - use connection details below:\n\n```\ntelnet [hostname] 35123\n```\n\nUse UTF-8 terminal encoding.\n\n## Running the Server\n``` diff\n- IMPORTANT - Python \u003e= 3.6.7 is required (Ubuntu \u003e= 18.04 LTS)!\n```\n1. Update your system `sudo apt update \u0026\u0026 sudo apt upgrade`\n2. Get the repo `git clone https://gitlab.com/bashrc2/AberMUSH`\n3. CD into 'AberMUSH' and install the server `sudo ./installer.sh`\n\nIf you want to add a firewall which only allows logins via ssh or telnet:\n\n``` bash\nsudo cp /opt/abermush/firewall.nft /etc/firewall.conf\nsudo apt -y install nftables\nsudo nft -f /etc/firewall.conf\nsudo echo '#!/bin/sh' \u003e /etc/network/if-up.d/firewall\nsudo echo 'nft flush ruleset' \u003e\u003e /etc/network/if-up.d/firewall\nsudo echo 'nft -f /etc/firewall.conf' \u003e\u003e /etc/network/if-up.d/firewall\nsudo chmod +x /etc/network/if-up.d/firewall\n```\n\nYou now should be able to connect to your server on `\u003cserver IP/hostname\u003e:35123`\n\n![AberMUSH](docs/cat.png)\n\n## Player Commands\n\nAll players can use the following commands:\n\n``` text\nbio [description]                       - Set a description of yourself\ngraphics [on|off]                       - Turn graphical content on or off\nchange password [newpassword]           - Change your password\nwho                                     - List players and where they are\nquit/exit                               - Leave the game\neat/drink [item]                        - Eat or drink a consumable\nspeak [language]                        - Switch to speaking a different language\nsay [message]                           - Says something out loud\nlook/examine                            - Examines the surroundings\ngo [exit]                               - Moves through the exit specified\nclimb though/onto [exit]                - Try to climb through or onto an exit\nmove/roll/heave [target]                - Try to move or roll a heavy object\njump to [exit]                          - Try to jump onto something\nattack/punch/kick/headbutt [target]     - Attack another player or NPC\nthrow [weapon] at [target]              - Throw a weapon at another player or NPC\nshove/trip                              - Try to knock down a target during an attack\nprone                                   - Lie down\nstand                                   - Stand up\ncheck inventory                         - Check the contents of your inventory\ntake/get [item]                         - Pick up an item\nput [item] in/on [item]                 - Put an item into or onto another one\ndrop [item]                             - Drop an item\nwhisper [target] [message]              - Whisper to a player in the same room\ntell/ask [target] [message]             - Send a tell message to another player or NPC\nuse/hold/pick/wield [item] [left|right] - Transfer an item to your hands\nstow                                    - Free your hands of items\nwear [item]                             - Wear an item\nremove/unwear [item]                    - Remove a worn item\nopen [item]                             - Open an item or door\nclose [item]                            - Close an item or door\npush [item]                             - Pushes a lever\npull [item]                             - Pulls a lever\naffinity [player name]                  - Shows your affinity level with another player\ncut/escape                              - Attempt to escape from a trap\nstep over tripwire [exit]               - Step over a tripwire in the given direction\ndodge                                   - Dodge an attacker on the next combat round\n```\n\n## Chess Commands\n\n![AberMUSH](docs/chess.jpg)\n\nIf you can find a chess board to play on:\n\n``` text\nchess                                   - Shows the board\nchess reset                             - Rests the game\nchess move [coords]                     - eg. chess move e2e3\nchess undo                              - undoes the last move\n```\n\n## Cards\n\nIf you can find a deck of cards:\n\n``` text\nshuffle                                 - Shuffles the deck\ndeal to [player names]                  - Deals cards\nhand                                    - View your hand of cards\nstick                                   - Stick with your current hand\nswap [card description]                 - Swaps a card\ncall                                    - Players show their hands\n```\n\n## Nine Men's Morris\n\nIf you can find a [Morris](https://en.wikipedia.org/wiki/Nine_men%27s_morris) board:\n\n``` text\nmorris                                  - Show the board\nmorris put [coordinate]                 - Place a counter\nmorris move [from coord] [to coord]     - Move a counter\nmorris take [coordinate]                - Remove a counter after mill\nmorris reset                            - Resets the board\n```\n\n## Spell Commands\n\nSome characters can use magic with the following commands:\n\n``` text\nprepare spells                          - List spells which can be prepared\nprepare [spell name]                    - Prepares a spell\nspells                                  - Lists your prepared spells\nclear spells                            - Clears your prepared spells list\ncast find familiar                      - Summons a familiar with random form\ndismiss familiar                        - Dismisses a familiar\ncast [spell name] on [target]           - Cast a spell on a player or NPC\n```\n\nSpells are defined within `spells.json` and the system for spellcasting is a simplified version of the one within conventional D\u0026D games. You prepare a spell, it gets added to your list and then you can cast it and it disappears from the prepared list. Some spells require certain items to be in the player's inventory.\n\n![AberMUSH](docs/lake.jpg)\n\n## Witch Commands\n\nWitches are the admins of the system, and have additional supernatural powers. The first user to create an account gains witch status. Additional witches may be assigned by appending them to the `witches` file, which is located in the same directory as `abermush.py` is run from.\n\n``` text\nclose registrations                - Closes registrations of new players\nopen registrations                 - Allows registrations of new players\nmute/silence [target]              - Mutes a player and prevents them from attacking\nunmute/unsilence [target]          - Unmutes a player\nfreeze [target]                    - Prevents a player from moving or attacking\nunfreeze [target]                  - Allows a player to move or attack\nteleport [room]                    - Teleport to a room\nsummon [target]                    - Summons a player to your location\nkick out/remove [target]           - Remove a player from the game\nblocklist                          - Show the current blocklist\nblock [word or phrase]             - Adds a word or phrase to the blocklist\nunblock [word or phrase]           - Removes a word or phrase to the blocklist\ndescribe \"room\" \"room name\"        - Changes the name of the current room\ndescribe \"room description\"        - Changes the current room description\ndescribe \"tide\" \"room description\" - Changes the room description when tide is out\ndescribe \"item\" \"item description\" - Changes the description of an item in the room\ndescribe \"NPC\" \"NPC description\"   - Changes the description of an NPC in the room\nconjure room [direction]           - Creates a new room in the given direction\nconjure npc [target]               - Creates a named NPC in the room\nconjure [item]                     - Creates a new item in the room\ndestroy room [direction]           - Removes the room in the given direction\ndestroy npc [target]               - Removes a named NPC from the room\ndestroy [item]                     - Removes an item from the room\nresetuniverse                      - Resets the universe, losing any changes from defaults\nshutdown                           - Shuts down the game server\n```\n\n### NPC Types\n\nNPCs defined within `def/npcs.json` have a few different modes. The rooms which they can occupy are defined within the `path` list and the ways in which they move is defined by the `moveType` parameter. Movement types are:\n\n * *cyclic* - Move from the start to the end of the list of rooms\n * *inverse cyclic* - Move from the end to the start of the list of rooms\n * *random* - Move to random rooms in the list\n * *patrol* - Move from the start to the end of the list, then back again\n * *follow* - Look for players and follow them around\n * *leader:name* - Follow a named leader, which may be a player or NPC\n\nIf no `moveType` is specified then random movement is the default.\n\nThe speed at which NPCs move between rooms is defined by `moveDelay` and `randomFactor` parameters. RandomFactor just makes the delay between movements not completely predictable.\n\n### NPC Presence\n\nNPCs may be present at certain times of day or days of the year. To define this use the `moveTimes` list within `npcs.json`.\n\n``` text\n\"moveTimes\": [[\"hour\",8,19],[\"day\",\"saturday\",\"sunday\"],[\"inactive\",1386]],\n```\n\nIn the above example the NPC will be active between 8:00 (8am) and 19:00 (7pm) on the weekend and when inactive will be in room 1386. So for example a cleric might be present at a church only on Sunday between certain hours and then be at a monestary at other times. If the `inactive` list isn't specified then when inactive an NPC will go to a default purgatory room.\n\nYou can also use `moveTimes` within `items.json` to specify items which are only present at certain times. However, these must be items having a weight value of zero so that they can't be taken.\n\n![AberMUSH](docs/crossbow.png)\n\n### NPC Conversations\n\nYou can create simple kinds of conversations with NPCs by editing `npcs.json` and adding line entries within the `conv` parameter. For example:\n\n``` text\n\"conv\" : [\n    [[\"serve\",\"beer\",\"?\"], \"Yes, of course\"],\n    [[\"serve\",\"wine\",\"?\"], \"We only serve the more disreputable wine\"],\n    [[\"have\",\"order\",\"like\",\"beer\",\"ale\",\"drink\",\"please\"],\"Here you go\",\"give\",\"114\"],\n    [[\"have\",\"order\",\"buy\",\"purchase\",\"trade\",\"like\",\"weapon\",\"dagger\",\"knife\",\"please\"],\"This weapon may come in handy on your adventures\",\"buy\",\"624\",\"1367\"]\n],\n```\n\nThis uses a simple \"bag of words\" matching, so `serve` and `wine` could be in any order.\n\nYou can then tell the NPC something like:\n\n``` text\nask inn-keeper Do you serve wine?\n```\n\nThe system will then try to match words within your `ask` command and pick the most appropriate reply:\n\n``` text\nthe old inn-keeper says: We only serve the more disreputable wine.\n```\n\nThe NPC can also give an item if some words are matched, or exchange/buy/barter an item such as a gold coin for a small dagger. The numbers refer to item numbers within `items.json`.\n\nPossible types of actions within NPC conversations are:\n\n``` text\ngive [item ID]                       - Gives an item\nteach [skill] [adjustment value]     - Adjusts a skill level\ntransport [room ID]                  - Moves the player to a different room\ntaxi [room ID] [itemID]              - Moves the player to a different room in exchange for an inventory item\ndate [dd/mm]                         - Conversation can only occur on a given day of the year\nbuy [obtain item ID] [give item ID]  - Obtains one item in exchange for another\nexperience [points]                  - Increase player experience\n```\n\nTo show an image during a conversation:\n\n``` text\n\"conv\" : [\n    [[\"have\",\"order\",\"like\",\"beer\",\"ale\",\"drink\",\"please\"],\"Here you go\",\"image:givedrink\",\"give\",\"114\"]\n],\n```\n\nIf an image then exists in `images/events` called `givedrink` then it will be shown when the conversation event happens.\n\nIf an NPC moves between rooms then you can make conversation lines dependent on being in a particular region.\n\n``` text\n\"conv\" : [\n    [[\"what\",\"you\",\"doing\",\"?\",\"region=cave\"],\"I'm digging for gold\"]\n    [[\"what\",\"you\",\"doing\",\"?\",\"region=garden\"],\"I'm doing some gardening\"]\n],\n```\n\nRegion names can be set within `rooms.json`, and could be for a single room or a group of rooms.\n\n### Spoken Languages\n\nPlayers and NPCs have their own languages: `common`, `dwarvish`, `elvish`, `draconic` and `druidic`. Goblins and humans may not be able to understand each other.\n\nThe language spoken and understood by NPCs can be defined with two parameters within `npcs.json`. `language` is a list of languages which the NPC understands and `speakLanguage` is the language which they are currently using to communicate.\n\n``` text\n\"speakLanguage\": \"common\",\n\"language\": [\"common\",\"dwarvish\"],\n```\n\nPlayers also have the same parameters and if they are multi-lingual then they can switch between languages using the `speak` command. For example:\n\n``` text\nspeak common\nspeak dwarvish\n```\n\n### Stateful NPC Conversations\n\nIt may be useful for an NPC to keep track of the state of your conversation and it's possible to do this via state variables. There is only one conversation state variable per NPC/player combination and it can be named anything you like. For example:\n\n``` text\n\"conv\" : [\n    [[\"order\",\"beer\",\"please\"],\"Free as in beer\",\"state:beer given\",\"give\",\"114\"],\n    [[\"state:beer given\",\"order\",\"beer\",\"please\"],\"Have another one then\",\"give\",\"114\"]\n],\n```\n\nHere whenever you ask for a beer the state variable `beer given` will be set for the NPC. If you subsequently ask for another beer the NPC gives a different response by matching the state variable. In this way you can have branching narratives dependent upon conversational context. Maybe an NPC only gives you some item after an appropriate sequence of dialogue.\n\n### NPC Conversation conditions\n\nIt's also possible to add extra conditions to the conversation response selection.\n\n``` text\n\"conv\" : [\n    [[\"order\",\"ale\",\"please\"],\"Have an ale!\",\"state:beer given\",\"give\",\"114\"],\n    [[\"strength\u003e90\",\"order\",\"ale\",\"please\"],\"I'm sorry, we don't serve bodybuilders here.\"]\n],\n```\nThe variables available are the various player attributes: `level`, `experience`, `strength`, `size`, `weight` (of inventory carried), `perception`, `endurance`, `charisma`, `intelligence`, `agility` and `luck`. You can match multiple conditions if necessary.\n\n![AberMUSH](docs/lava.jpg)\n\n### Conditional Room Descriptions\n\nYou may want the description of a room to change if some condition is met. For example, within `rooms.json`:\n\n``` text\n\"conditional\": [\n    [\"hour\",\"\u003c2\",\"The night's drinking is over and amidst occasional complaining the inn-keeper is kicking the remaining crowd out of this disreputable establishment. Displaced coasters, drug paraphenalia and cutlery remain strewn around. The door leading back out looks inviting.\"],\n    [\"hour\",\"\u003c10\",\"Not much is going on within this disreputable establishment. It's dark, customers have been kicked out and the bar is empty. The inn-keeper is still around, cleaning up spilt ale, opium pipes, lost darts and randomly displaced cutlery. The door leading back out looks tempting.\"],\n    [\"date\",\"25/12\",\"Punters are engaging in festive celebrations in this disreputable boozing establishment. The inn-keeper looks busy behind the bar, and also slightly under the influence of the clouds of opium smoke wafting over from the merrymakers. The door leading back out looks tempting.\"],\n    [\"hold\",\"114\",\"You stare dispondently into your flagon of ale, but matters don't seem to improve. Is it worth drinking a beverage this cheap, you ask yourself. There's a door leading out.\"],\n    [\"hold\",\"lightsource\",\"The dark street is illuminated by the light you are holding.\"],\n    [\"rain\",\"true\",\"Puddles form in the street.\"],\n    [\"sunrise\",\"true\",\"You see the sun rise over the tops of the trees.\"]\n    [\"sunset\",\"true\",\"You see the sun set below the horizon.\"]\n],\n```\n\nThis provides different room descriptions in the morning to at other times.\n\nPossible condition types are `hour`, `month`, `season`, `dayofweek`, `date`, `skill`, `rain`, `rainmorning`, `rainafternoon`, `rainevening`, `rainnight`, `sunrise`, `sunset`, `hold` and `wear`.\n\nYou can use this to do things like describing a dark cave by default but changing the description if you are holding a lamp, of having different descriptions for different seasons of the year.\n\n``` text\n\"conditional\": [\n    [\"season\",\"spring\",\"You are in an orchard with blossoming trees\"],\n    [\"season\",\"summer\",\"Bright sunlight casts shadows through the trees\"],\n    [\"season\",\"autumn\",\"The ground is covered with leaves.\"],\n    [\"season\",\"winter\",\"The trees look bleak and bare\"]\n],\n```\n\nSeasons in this system are not accelerated, so if it's summer where you are it will be summer in the MUSH.\n\nIf you want to specify a particular image which will show when a particular condition is true then you can add a fourth parameter which is a reference to the room image filename. For example:\n\n``` text\n    [\"hold\",\"lightsource\",\"The dark street is illuminated by the light you are holding.\",\"roomwithlight\"]\n```\n\nThis would correspond to the image within *images/rooms/roomwithlight*, and be shown instead of the usual room image when a light source is held.\n\nIn rooms which need a light source items won't be noticed until at least one player is holding a light source. Hence things can be hidden in the dark.\n\n![AberMUSH](docs/door.png)\n\n### Adding Doors and Opening things\n\nTo add a door, or other object to be opened or closed you will need a pair of items, like the following:\n\n``` text\n    \"429\": {\n        \"name\": \"old trapdoor\",\n        ...\n        \"state\": \"closed\",\n        \"exitName\": \"up|down\",\n        \"linkedItem\": 430,\n        \"lockedWithItem\": 0,\n        \"open_description\": \"As you push open the trapdoor bright light streams in.\",\n        \"open_failed_description\": \"You try to open the trapdoor, but it's locked.\",\n        \"close_description\": \"You close the trapdoor and it takes a few moments for your eyes to adjust to the darkness.\",\n        \"exit\": \"$rid=433$\"\n    },\n    \"430\": {\n        \"name\": \"old trapdoor\",\n        ...\n        \"state\": \"closed\",\n        \"exitName\": \"down|up\",\n        \"linkedItem\": 429,\n        \"lockedWithItem\": 0,\n        \"open_description\": \"You carefully lift open the trapdoor. It looks dark down there.\",\n        \"open_failed_description\": \"You try to lift the trapdoor, but it's locked down.\",\n        \"close_description\": \"You gently close the trapdoor\",\n        \"exit\": \"$rid=431$\"\n    },\n```\n\nThese are the same trapdoor as seen from two rooms. The `linkedItem` parameter links the two and the `exit` parameter defines which room to go to when going through. Exits called `down` and `up` are added if the trapdoor is open.\n\nYou should make some vague suggestion that these items can be opened within their `long_description` parameter.\n\nIf you need a key to open the door then specify the item number within the `lockedWithItem` parameter.\n\n### Lever Operated Doors\n\nIt's possible to have doors which can't be manually opened but are lever operated.\n\nTo define a lever:\n\n``` text\n    \"518\": {\n        \"name\": \"ivory lever\",\n        \"short_description\": \"There is an ivory lever set in the wall, next to the door.\",\n        \"long_description\": \"It is highly polished, and the end is ornately carved in the shape of a skull. It is in the up position.\",\n        \"state\": \"lever up\",\n        \"open_description\": \"With great effort you yank the lever down\",\n        \"open_failed_description\": \"It doesn't appear to have any handle\",\n        \"close_description\": \"You push the lever up\",\n        \"lockedWithItem\": 0,\n        \"exitName\": \"east|west\",\n        \"linkedItem\": 526,\n        \"exit\": \"$rid=528$\",\n    },\n```\n\nHere `linkedItem` is the item number of the door which will be opened and `exit` is the room which it goes to. `exitName` defines the door as heading east from its location, with the opposite direction back to this location being west. The `state` variable can be `lever up` or `lever down`.\n\nThe door is then defined with:\n\n``` text\n    \"526\": {\n        \"name\": \"wooden door\",\n        \"short_description\": \"The door is closed.\",\n        \"long_description\": \"The old wooden door made from solid oak beams is closed.\",\n        \"state\": \"closed\",\n        \"lockedWithItem\": 518,\n        \"exitName\": \"east|west\",\n        \"linkedItem\": 527,\n        \"exit\": \"$rid=528$\",\n    },\n    \"527\": {\n        \"name\": \"wooden door\",\n        \"short_description\": \"The door is closed.\",\n        \"long_description\": \"The old wooden door made from solid oak beams is closed.\",\n        \"state\": \"closed\",\n        \"lockedWithItem\": 520,\n        \"exitName\": \"west|east\",\n        \"linkedItem\": 526,\n        \"exit\": \"$rid=530$\",\n    }\n```\n\n`lockedWithItem` indicates that the door can only be opened with the lever with the given item number.\n\nYou can then use the following command to open the door:\n\n``` text\npull ivory lever\n```\n\nYou can get as devious as you like with this and have levers which open or close doors in some entirely different location, or one way doors which once shut with the lever can't be opened from the other side.\n\n### Jumping\n\nThe *jump* command can be used to jump onto an item. For example, an item can be defined as follows:\n\n``` text\n    \"1817\": {\n        \"name\": \"precarious ledge\",\n        \"short_description\": \"The precarious ledge is across the chasm\",\n        \"long_description\": \"The precarious ledge is across the chasm\",\n        \"jumpTo\": \"You take a running jump onto the ledge\",\n        \"exit\": \"$rid=1835$\",\n        ...\n```\n\nThe exit is the room to move to when jumping.\n\nYou can then use the command:\n\n``` text\njump onto ledge\n```\n\n### Heaving/Rolling\n\nSometimes you want to move an item in a manner which isn't the same thing as opening.\n\n``` text\n    \"2971\": {\n        \"name\": \"tomb stone\",\n        \"short_description\": \"A giant spherical stone covers the entrance to the tomb.\",\n        \"long_description\": \"A giant spherical stone covers the entrance to the tomb.\",\n        \"heave\": \"You roll the giant stone to one side and enter the tomb.\",\n        \"exit\": \"$rid=4356$\",\n        ...\n```\n\nThe exit is the room to move to when rolling.\n\nYou can then use the command:\n\n``` text\nroll the tomb stone\n```\n\n### Climbing through windows and boarding boats\n\nYou can add items to a room such as windows which the player can then climb through. Size restrictions apply and so this could be another way to escape from ogres or dragons. This can also be used to set up non-obvious exits as a puzzle, or for boarding boats.\n\n``` text\n    \"1293\": {\n        \"name\": \"large window\",\n        \"short_description\": \"A huge window looks out across the snows.\",\n        \"long_description\": \"It looks out over the snows. You could climb out of the window and down the snowbanks outside, providing of course they will take your weight. It is difficult to tell if they will though.\",\n        \"climbThrough\": \"With considerable effort you scramble through the window.\",\n        \"exit\": \"$rid=1294$\",\n        ...\n```\n\nThe exit is the room to move to when climbing through.\n\nYou can then use the command:\n\n``` text\nclimb through window\n```\n\nYou can also make climbing conditional upon wearing a particular item.\n\n``` text\n    \"1293\": {\n        \"name\": \"ice wall\",\n        \"short_description\": \"A huge wall of ice.\",\n        \"climbWhenWearing\": [7358, 6562],\n        \"climbThrough\": \"Wearing the ice boots you climb up the wall of ice.\",\n        \"exit\": \"$rid=1294$\",\n        ...\n```\n\nIf there are items in the room which the player might try to climb, but which aren't climbable then you can specify a failure message for that.\n\n``` text\n    \"3713\": {\n        \"name\": \"snowman\",\n        \"short_description\": \"A giant snowman.\",\n        \"long_description\": \"A giant snowman.\",\n        \"climbFail\": \"You try to climb onto the snowman, but slip back down again.\",\n        ...\n```\n\n### Visibility\n\nSome wearable items may allow the player to see things which are otherwise hidden. So for example wearing a certain necklace might allow you to see an ancester spirit or hidden treasure.\n\nWithin `items.json` and `npcs.json` the list called `visibleWhenWearing` can contain the ID numbers of wearable items. If the player is wearing any of the items in the list then they will be able to see the NPC or item.\n\n![AberMUSH](docs/chest.png)\n\n### Failing to take items\n\nIf an item has a weight of zero then it is fixed in place. If you want to provide a custom message when a player tries to take an item and fails then this can be specified within `items.json` with the parameter *takeFail*.\n\n``` json\n\"517\": {\n    \"name\": \"manacled skeleton\",\n    \"long_description\": \"There is a skeleton chained to the wall.\",\n    \"takeFail\": \"You try to remove the skeleton but it's firmly chained to the wall.\",\n    \"weight\": 0,\n    ...\n}\n```\n\n### Containers, Chests and Tables\n\nOther than opening and closing doors you may also want to have items which can be opened or closed, and have things removed or put into them. For example a treasure chest containing gold coins. To define an item as openable the relevant attributes are similar to the following:\n\n``` text\n    \"207\": {\n        \"name\": \"clothes chest\",\n        ...\n        \"state\": \"container closed\",\n        \"open_description\": \"Tiny moths flutter out as you open the clothes chest.\",\n        \"close_description\": \"The clothes chest closes with a satisfying thud.\",\n        \"contains\": [\"107\",\"1386\",\"1389\",\"1390\"],\n        \"useTimes\": 10,\n        \"lockedWithItem\": 0,\n    },\n```\n\nThe state of the item can be `container open` or `container closed`. You can then use commands such as:\n\n``` text\nopen chest\nexamine chest\ntake hat from chest\nwear hat\nclose chest\n```\n\nThe `useTimes` parameter defines the maximum number of items which can be put into a container.\n\nSimilar to doors, items may be locked with another item which could be a key. Tables can be a special type of always open item.\n\n``` text\n    \"1289\": {\n        \"name\": \"inn table\",\n        ...\n        \"state\": \"container open always\",\n    },\n```\n\nYou can then use a command such as:\n\n``` text\nput hat on table\n```\n\nIt's also possible to have items which can be opened and closed but which can't have things put into them. Use `noput` within the state parameter to indicate this.\n\n\n``` text\n    \"1289\": {\n        \"name\": \"dusty book\",\n        ...\n        \"state\": \"container closed noput\",\n        \"open_description\": \"A dust cloud emerges as you open the ancient tome.\",\n        \"close_description\": \"You close the book and blow off some dust from its cover.\",\n    },\n```\n\nWith commands such as:\n\n``` text\nopen book\nclose book\n```\n\n### Consumables\n\nFood or drink can be defined by setting `edible` to a non-zero value within `items.json`. If the value is negative then the item is a type of poison.\n\n### Weather\n\nThe system includes a dynamic weather simulation with varying seasonal and daily temperatures, passing clouds and rain. The ambient weather conditions may affect your combat performance, especialy if you are wearing armor or carrying a lot of weight.\n\n### Item activated exits\n\nSome exits may be activated only when the player is wearing or holding a particular item. Within `rooms.json` you can add something like:\n\n``` json\n\"exitsWhenWearing\": [\n    [\"east\",\"123\",\"$rid=7160$\"]\n],\n```\n\nSo that an exit to the east will become available when you are wearing the item with number 123. This is like holding open a portal which other players can then use even if they are not wearing the same item.\n\n![AberMUSH](docs/tide.png)\n\n### Tides\n\nFor coastal locations an optional alternative description may be entered into `tideOutDescription`. When the tide is in the default `description` parameter will be used.\n\nIt is also possible to specify exits which only become available when the tide is out, to implement [tidal islands](https://en.wikipedia.org/wiki/Tidal_island).\n\n``` json\n\"tideOutExits\": {\n    \"east\": \"$rid=7160$\"\n},\n```\n\n![AberMUSH](docs/combat.png)\n\n### Players in Combat\n\nCollecting weapons or armor will alter your chances of success in combat. In order to use a weapon you first need to be holding it. Merely having it in your inventory isn't enough for it to be effective. For example:\n\n``` text\ntake dagger\nhold dagger\n```\n\nYou can also choose which hand.\n\n``` text\nhold dagger right\nhold dagger left\n```\n\nWith the possibility of using two weapons at the same time. However, some weapons require two hands to use and this is specified by the `bothHands` parameter in `items.json`.\n\nSimilar applies with armour:\n\n\n``` text\ntake chainmail\nwear chainmail\n```\n\nTo see what you or other players are wearing or holding use the `bio` command or:\n\n``` text\nexamine [player]\n```\n\nTo start a fight you can then use the `attack` or `throw` commands. If you throw a weapon the damage it does may be higher but it may also then be picked up by any other player or NPC and used against you.\n\nThe `mod_str` parameter within an item which is a weapon defines how much damage it can inflict during combat. `mod_endu` defines how much protection a wearable item will provide against attacks.\n\nThere is a limit to how much weight you can carry and carrying or wearing a lot of heavy items will reduce your agility.\n\nIf you are attacked then your `hit points` will decrease. Rest, or the consumption of food or drink, can restore your hit points.\n\nThe type or armor which players (including NPCs) are wearing can also modify their agility, altering their combat performance. Agility values for armor items can be set with the `mod_agi` parameter. Negative values mean that wearing the item slows the player down. Positive values improve fighting performance.\n\nWhile fighting you can use the `dodge` command to try to evade the attacker's next blow. You will miss a turn when trying to attack, but have less chance of being hit in the current round. Success in dodging depends on your `luck` and `agility`, which can vary depending upon items carried or worn and the weather/terrain.\n\n### NPCs in Combat\n\nNPCs are able to pick up and use any weapons or armor available in the vicinity. For some types of NPC, such as small animals, this isn't appropriate and so it's possible to set `canWear` and `canWield` parameters to zero within `npcs.json` if necessary.\n\n### Parental Controls\n\nIf you don't want certain words or phrases to be used by players then you can create a file called `blocked.txt` containing them in the same directory that you run `abermush.py` from. Entries can be on separate lines or comma separated and the matching is case insensitive. This then alters the `say`, `tell` and `whisper` commands such that recipients won't receive messages containing blocked text.\n\nYou can also use the commands `block` and `unblock` to update the blocklist without restarting the server.\n\n### Affinity Levels\n\nThe system keeps track of affinity levels between players, including between players and NPCs, via sentiment analysis and friendly or unfriendly actions. This enables NPCs to adjust their narrative based upon how friendly or hostile a player is towards them or other individuals which they know. For example:\n\n``` text\n\"conv\" : [\n    [[\"affinity\u003e0\",\"serve\",\"ale\",\"?\"], \"Yes, of course\"],\n    [[\"affinity\u003c0\",\"serve\",\"ale\",\"?\"], \"Begone, scoundrel!\"]\n],\n```\n\nIn some cases this may mean that you need to sufficiently charm an NPC before it will give you an item, skill or clue.\n\nYou can also see your affinity level with other players or NPCs with the command:\n\n``` text\naffinity [player name]\n```\n\n![AberMUSH](docs/familiars.png)\n\n### Interacting with Familiars\n\nSome characters can have familiars, which are arcane spirits in the form of an animal and with a telepathic link to the player who summons them. Familiars follow the player and can also be commanded to scout, hide or distract other players. They don't have much strength or intelligence and so can easily be killed, but can be summoned again if that happens. Every time a familiar is summoned it takes a random animal form.\n\nTo summon a familiar:\n\n``` text\nprepare find familiar\ncast find familiar\n```\n\nor witches may use the `conjure` command:\n\n``` text\nconjure familiar\n```\n\nBy default the familiar will follow you, or you can tell it to:\n\n``` text\nask familiar to follow\n```\n\nYou can have it scout around in the local area:\n\n``` text\nask familiar to scout\n```\n\nor in a particular direction:\n\n``` text\nask familiar to scout north\n```\n\nWhen scouting familiars will be visible and attackable by other players or NPCs.\n\nFamiliars are small and so can easily conceal themselves in obscure nooks and corners. To make the familiar hide:\n\n``` text\nask familiar to hide\n```\n\nOnce hidden a familiar will remain in place regardless of where the player moves. Only the player can see the familiar once it is hidden.\n\nIt is also possible to ask the familiar what it sees. Because it is a spirit from the arcane realm it is only able to describe the scene in abstract elemental terms. It can see other players and has a sense about whether they are friendly and how large they are.\n\n``` text\nask familiar what do you see?\n```\n\n### Room height and capacity\n\nWithin `rooms.json` the parameters `maxPlayers` and `maxPlayerSize` can be used to define the maximum number of players which a room can contain (including NPCs) and also the height of the room. The numbers corresponding to player size are:\n\n``` text\n0 - Tiny (raven, cat, imp)\n1 - Small (dwarf, halfling, goblin, gremlin)\n2 - medium (human, elf, witch)\n3 - Large (giant)\n4 - Huge (ogre, dragon)\n```\n\nThus you can have rooms which are accessible to halflings or familiars but not to humans, which could add an extra element to the story. Maybe certain rooms enable humans to escape from giants.\n\nFor small rooms you might want to only allow one or two players to occupy it at any point in time.\n\nIf these values are set to -1 then there are no limits on player size or numbers.\n\n### Traps\n\nVarious kinds of traps can cause minor damage to players or prevent them from moving temporarily. After being activated they get reset again after a period of time.\n\nTo set a dart trap when exiting north within `rooms.json`:\n\n``` text\n\"trap\": {\n    \"trapType\": \"dart\",\n    \"trapExit\": \"north\",\n    \"trapPerception\": 2,\n    \"trapActivation\": \"tripwire\",\n    \"trapActivationProbability\": 100,\n    \"trapActivationTime\": 0,\n    \"trapActivationDescription\": \"\",\n    \"trapEscapeMethod\": \"\",\n    \"trapDamagedMax\": 1,\n    \"trapDamaged\": 0,\n    \"trapEscapeDescription\": \"\",\n    \"trapDuration\": \"0 min\",\n    \"trapPenaltyType\": \"hp\",\n    \"trapPenalty\": 10,\n    \"trapResetTime\": \"2 hours\",\n    \"trappedPlayers\": []\n},\n```\n\nThis causes a sting of up to 10 hit points. `trapPerception` specifies the minimum perception (`per` value in player json file) needed to see the trap, and it gets reset after two hours if activated. `trapActivationProbability` indicates that the trap always works 100% of the time when the tripwire is crossed.\n\nTo create a falling net trap activated by a pressure plate:\n\n``` text\n\"trap\": {\n    \"trapType\": \"net\",\n    \"trapExit\": \"north\",\n    \"trapPerception\": 2,\n    \"trapActivation\": \"pressure\",\n    \"trapActivationProbability\": 100,\n    \"trapActivationTime\": 0,\n    \"trapActivationDescription\": \"\",\n    \"trapEscapeMethod\": \"slashing\",\n    \"trapDamagedMax\": 20,\n    \"trapDamaged\": 0,\n    \"trapEscapeDescription\": \"\",\n    \"trapDuration\": \"5 min\",\n    \"trapPenaltyType\": \"hp\",\n    \"trapPenalty\": 0,\n    \"trapResetTime\": \"2 hours\",\n    \"trappedPlayers\": []\n},\n```\n\nWhen the net falls on a player it will prevent them from moving for up to 5 mins. During that time they can try to cut themselves out if they are holding a `slashing` type weapon. They will need to do 20 points of damage to the net to escape. Hence with a sword it may be easy to break free, but with a small dagger it may take a while. If you're trapped by a net then other players or NPCs have an advantage when attacking you.\n\nTo create a tar pit trap activated when a player tries to move in a given direction:\n\n``` text\n\"trap\": {\n    \"trapType\": \"tar pit\",\n    \"trapExit\": \"west\",\n    \"trapPerception\": 2,\n    \"trapActivation\": \"move\",\n    \"trapActivationProbability\": 40,\n    \"trapActivationTime\": 0,\n    \"trapActivationDescription\": \"\",\n    \"trapEscapeMethod\": \"wait\",\n    \"trapDamagedMax\": 99999,\n    \"trapDamaged\": 0,\n    \"trapEscapeDescription\": \"\",\n    \"trapDuration\": \"1 min\",\n    \"trapPenaltyType\": \"hp\",\n    \"trapPenalty\": 0,\n    \"trapResetTime\": \"30 mins\",\n    \"trappedPlayers\": []\n},\n```\n\nWhen you try to move west you will get stick in the tar pit 40% of the time. Once stuck the only thing you can do is to wait for one minute. Other possible traps are \"ditch\", \"marsh\" and \"pit\".\n\n### Room images\n\nThese are 8 bit ANSI images, created using climage. They're derived from CC0 licensed images on https://free-images.com or Wikimedia.\n\nTo install:\n\n``` bash\nsudo apt install catimg\n```\n\nTo convert an image:\n\n``` bash\ncatimg -w 120 myimage.jpg \u003e images/rooms/[rid]\n```\n\nThe numbers should correspond to room ID or item ID.\n\nYou can also add a night time version of the image by appending _night to the filename.\n\n``` bash\ncatimg -w 120 myimage.jpg \u003e images/rooms/[rid]_night\n```\n\n\n![AberMUSH](docs/creators.png)\n\n### Constructing the Universe\n\nAberMUSH is already large by the standards of the late 1980s when AberMUD was originally developed, having about 600 rooms. But you don't have to stop there. Witches have the power to alter the universe arbitrarily by adding or removing rooms, items and NPCs interactively while the game is in progress. They can also change the descriptions.\n\nTo change the description of a room:\n\n``` text\ndescribe \"This is a new description of the room.\"\nlook\n```\n\nYou can also change the name of the room:\n\n``` text\ndescribe \"room\" \"New room title\"\n```\n\nTo create and describe a new room:\n\n``` text\nconjure room south\ngo south\ndescribe \"room\" \"Cave Entrance\"\ndescribe \"The cave entrance is narrow with rocks strewn around.\"\n```\n\nTo remove the room just created:\n\n``` text\ngo north\ndestroy room south\n```\n\nYou can also create and remove items in a room:\n\n``` text\nconjure sword\ndestroy sword\n```\n\nAnd similar with NPCs:\n\n``` text\nconjure npc \"Huge Ogre\"\ndescribe npc \"The ogre is huge and angry looking.\"\ndestroy ogre\n```\n\nIf you make any blunders then you can reset the universe back to its original state with the `resetuniverse` command, then restart the server.\n\n### Markets\n\nDifferent types of markets are defined within *def/markets.json*. If a room name matches a market type then it is possible to buy or sell within that room, using the *inventory* command to see what is on offer. The *sells* parameter indicates that certain items may only be sold within the market. The *trades* parameter indicates items which can be bought or sold.\n\n### Culture and Regions\n\nEach room can be assigned a region, and within *def/cultures.json* the regions for each culture can be defined.\n\nItems can be assigned a culture so that if they are being sold within a market then the types of items can be culturally specific to the region.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbashrc2%2Fabermush","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbashrc2%2Fabermush","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbashrc2%2Fabermush/lists"}