#!/usr/bin/env python
""" A simple Multi-User Dungeon (MUD) game. Players can talk to each
other , examine their surroundings and move between rooms .
author : Mark Frimston - mfrimston @gmail.com
"""
import time
import json
# import the MUD server class
from mudserver import MudServer
with open ( ' rooms.json ' , ' r ' ) as f :
rooms = json . load ( f )
# stores the players and npcs in the game
players = { }
# start the server
mud = MudServer ( )
# main game loop. We loop forever (i.e. until the program is terminated)
while True :
# pause for 1/5 of a second on each loop, so that we don't constantly
# use 100% CPU time
time . sleep ( 0.2 )
# 'update' must be called in the loop to keep the game running and give
# us up-to-date information
mud . update ( )
# go through any newly connected players
for id in mud . get_new_players ( ) :
# add the new player to the dictionary, noting that they've not been
# named yet.
# The dictionary key is the player's id number. We set their room to
# None initially until they have entered a name
# Try adding more player stats - level, gold, inventory, etc
players [ id ] = {
" name " : None ,
" room " : None ,
}
# send the new player a prompt for their name
mud . send_message ( id , """ \r
_ _ _ \r
| | _ _____ _ | | _ _ __ _ _ | | __ \r
| __ / _ \ \/ / __ | ' _ \ | | | | ' _ \ \r
| | | __ / > < | | _ | | _ ) | | _ | | | _ ) | \r
\__ \___ / _ / \_ \ __ | . __ / \__ , _ | _ . __ / \r
| _ | \r
\r \r
Hi there ! This is the multiplayer , text - based version of the Experimental Publishing masters at PZI . How about you begin by letting us know what you want to be called ? Then press enter .
""" )
# go through any recently disconnected players
for id in mud . get_disconnected_players ( ) :
# if for any reason the player isn't in the player map, skip them and
# move on to the next one
if id not in players :
continue
# go through all the players in the game
for pid , pl in players . items ( ) :
# send each player a message to tell them about the diconnected
# player
mud . send_message ( pid , " \r {} quit the game " . format (
players [ id ] [ " name " ] ) )
# remove the player's entry in the player dictionary
del ( players [ id ] )
# go through any new commands sent from players
for id , command , params in mud . get_commands ( ) :
# if for any reason the player isn't in the player map, skip them and
# move on to the next one
if id not in players :
continue
# if the player hasn't given their name yet, use this first command as
# their name and move them to the starting room.
if players [ id ] [ " name " ] is None :
players [ id ] [ " name " ] = command
players [ id ] [ " room " ] = " Corridor "
# go through all the players in the game
for pid , pl in players . items ( ) :
# send each player a message to tell them about the new player
mud . send_message ( pid , " {} has logged in. " . format (
players [ id ] [ " name " ] ) )
# send the new player a welcome message, and a description of the starting room
mud . send_message ( id , " Welcome to textpub, " + players [ id ] [ " name " ] + " . " + rooms [ players [ id ] [ " room " ] ] [ " description " ] + " Type ' help ' for a list of commands. Have fun! " )
# each of the possible commands is handled below. Try adding new
# commands to the game!
# 'help' command
elif command == " help " :
# send the player back the list of possible commands
mud . send_message ( id , " Commands: " )
mud . send_message ( id , " say <message> - Says something out loud, "
+ " e.g. ' say Hello ' " )
mud . send_message ( id , " look - Examines the "
+ " surroundings, e.g. ' look ' " )
mud . send_message ( id , " go <exit> - Moves through the exit "
+ " specified, e.g. ' go outside ' " )
# 'say' command
elif command == " say " :
# go through every player in the game
for pid , pl in players . items ( ) :
# if they're in the same room as the player
if players [ pid ] [ " room " ] == players [ id ] [ " room " ] :
# send them a message telling them what the player said
mud . send_message ( pid , " {} says: {} " . format (
players [ id ] [ " name " ] , params ) )
# 'look' command
elif command == " look " :
# store the player's current room
rm = rooms [ players [ id ] [ " room " ] ]
# send the player back the description of their current room
mud . send_message ( id , rm [ " description " ] )
playershere = [ ]
# go through every player in the game
for pid , pl in players . items ( ) :
# if they're in the same room as the player
if players [ pid ] [ " room " ] == players [ id ] [ " room " ] :
# ... and they have a name to be shown
if players [ pid ] [ " name " ] is not None :
# add their name to the list
playershere . append ( players [ pid ] [ " name " ] )
# go through every npc in the game
for pid in mud . npcs . keys ( ) :
# if they're in the same room as the player
if mud . npcs [ pid ] . room == players [ id ] [ " room " ] :
# ... and they have a name to be shown
if mud . npcs [ pid ] . name is not None :
# add their name to the list
playershere . append ( mud . npcs [ pid ] . name )
# send player a message containing the list of players in the room
mud . send_message ( id , " Players here: {} " . format (
" , " . join ( playershere ) ) )
# send player a message containing the list of exits from this room
mud . send_message ( id , " Exits are: {} " . format (
" , " . join ( rm [ " exits " ] ) ) )
# 'go' command
elif command == " go " :
# store the exit name
ex = params . lower ( )
# store the player's current room
rm = rooms [ players [ id ] [ " room " ] ]
# if the specified exit is found in the room's exits list
if ex in rm [ " exits " ] :
# go through all the players in the game
for pid , pl in players . items ( ) :
# if player is in the same room and isn't the player
# sending the command
if players [ pid ] [ " room " ] == players [ id ] [ " room " ] \
and pid != id :
# send them a message telling them that the player
# left the room
mud . send_message ( pid , " {} left via exit ' {} ' " . format (
players [ id ] [ " name " ] , ex ) )
# update the player's current room to the one the exit leads to
players [ id ] [ " room " ] = rm [ " exits " ] [ ex ]
rm = rooms [ players [ id ] [ " room " ] ]
# print(players[id]["name"] + " moved to the " + players[id]["room"])
# go through all the players in the game
for pid , pl in players . items ( ) :
# if player is in the same (new) room and isn't the player
# sending the command
if players [ pid ] [ " room " ] == players [ id ] [ " room " ] \
and pid != id :
# send them a message telling them that the player
# entered the room
mud . send_message ( pid ,
" {} arrived via exit ' {} ' " . format (
players [ id ] [ " name " ] , ex ) )
# send the player a message telling them where they are now
mud . send_message ( id , " You have entered the {} " . format (
players [ id ] [ " room " ] ) )
# the specified exit wasn't found in the current room
else :
# send back an 'unknown exit' message
mud . send_message ( id , " Unknown exit ' {} ' " . format ( ex ) )
# Item commands, to be completed
# get command
elif command == " get " :
mud . send_message ( id , " You got it " )
# drop command
elif command == " drop " :
mud . send_message ( id , " You dropped it " )
# make command
elif command == " made " :
mud . send_message ( id , " You made a " )
# some other, unrecognised command
else :
# send back an 'unknown command' message
mud . send_message ( id , " Unknown command ' {} ' " . format ( command ) )