added some NPCs, data in JSON, visual stuff

fruitual
Stephen Kerr 2 years ago
parent 08ee7395c1
commit 21f634ef7a

@ -1,4 +1,9 @@
MUD Pi textpub
======
This is a MUD based on the xpub studios.
Original readme from MUD Pi
====== ======
A simple text-based Multi-User Dungeon (MUD) game, which could be run on a A simple text-based Multi-User Dungeon (MUD) game, which could be run on a

@ -12,6 +12,34 @@ import socket
import select import select
import time import time
import sys import sys
import random
import json
with open('rooms.json', 'r') as f:
rooms = json.load(f)
chomsky_phrases= [
{
"phrasetext": "hello! My name is Noam, welcome to xpub",
"qtext" : "Who are you?",
"responses": [1,2],
},
{
"phrasetext": "I'm here to tell you about language",
"qtext" : "What are you doing here?",
"responses": [0,2,3],
},
{
"phrasetext": "The obscure language of postmodern, leftist philosophers gives little aid to the working classes",
"qtext" : "What's language?",
"responses": [0,1,3],
},
{
"phrasetext": "I was never aware of any other option but to question everything.",
"qtext" : "Do you only answer questions?",
"responses": [0],
}
]
class MudServer(object): class MudServer(object):
@ -46,6 +74,39 @@ class MudServer(object):
self.buffer = buffer self.buffer = buffer
self.lastcheck = lastcheck self.lastcheck = lastcheck
class NPC(object):
"""Holds information about a non player character"""
def __init__(self, name, room, speed, outer_instance):
self.name = name
self.room = room
self.phrases = chomsky_phrases
self.conversation_state = 0
self.walker = 1
self.walkspeed = speed #time in seconds
self.starttime = time.time()
self.outer_instance = outer_instance
self.outer_instance.npcs[self.name] = self
# The npc just changes room on this function for now. it is called as part of the updateNPCLocations function
def move(self, room):
self.room = room
# The npc should be able to say things to you
# Each interaction is a conversation, you are presented with (two) responses which bring
# you down different paths of the conversation. States of the conversation are like rooms
# and responses are like exits. Eventually could this be more random, from a short list of
# possible interactions or responses?
def interact(self):
pass
# say(json.phrases[conversation_state])
# print the questions for possible responses
# wait for user response
# self.conversation_state = based on user response
# End of NPC class-------------------------------------------------
# Used to store different types of occurences # Used to store different types of occurences
_EVENT_NEW_PLAYER = 1 _EVENT_NEW_PLAYER = 1
_EVENT_PLAYER_LEFT = 2 _EVENT_PLAYER_LEFT = 2
@ -111,6 +172,11 @@ class MudServer(object):
# start listening for connections on the socket # start listening for connections on the socket
self._listen_socket.listen(1) self._listen_socket.listen(1)
# adding npcs (for testing purposes?)
self.npcs = {}
self.chomsky = self.NPC("chomsky","Corridor",20, self)
self.mario = self.NPC("mario","Corridor",50, self)
def update(self): def update(self):
"""Checks for new players, disconnected players, and new """Checks for new players, disconnected players, and new
messages sent from players. This method must be called before messages sent from players. This method must be called before
@ -123,6 +189,7 @@ class MudServer(object):
self._check_for_new_connections() self._check_for_new_connections()
self._check_for_disconnected() self._check_for_disconnected()
self._check_for_messages() self._check_for_messages()
self.updateNPCLocations()
# move the new events into the main events list so that they can be # move the new events into the main events list so that they can be
# obtained with 'get_new_players', 'get_disconnected_players' and # obtained with 'get_new_players', 'get_disconnected_players' and
@ -183,7 +250,7 @@ class MudServer(object):
""" """
# we make sure to put a newline on the end so the client receives the # we make sure to put a newline on the end so the client receives the
# message on its own line # message on its own line
self._attempt_send(to, message+"\n\r") self._attempt_send(to, message+"\r\n\r\n")
def shutdown(self): def shutdown(self):
"""Closes down the server, disconnecting all clients and """Closes down the server, disconnecting all clients and
@ -403,3 +470,11 @@ class MudServer(object):
# return the contents of 'message' which is either a string or None # return the contents of 'message' which is either a string or None
return message return message
def updateNPCLocations(self):
# global npcs
for i in self.npcs:
if (time.time() - self.npcs[i].starttime > self.npcs[i].walkspeed):
self.npcs[i].move(random.choice(list(rooms.keys())))
self.npcs[i].starttime = time.time()
# print(self.npcs[i].name + " moved to " + self.npcs[i].room)

@ -0,0 +1,10 @@
{
"mario" : {
"name" : "mario",
"room" : "Aquarium"
},
"marx" : {
"name" : "marx",
"room" : "Corridor"
}
}

@ -0,0 +1,26 @@
{
"Studio": {
"name": "Studio",
"description": "You're in a cosy studio. It smells a bit like soup.",
"exits": {"south": "Corridor"}
},
"Office": {
"name": "Office",
"description": "You're in an office with glass windows to the corridor.",
"exits": {"east": "Corridor", "south": "artificial research station"}
},
"Corridor": {
"name": "Corridor",
"description": "You're in a short corridor with doors on three sides.",
"exits": {"north": "Studio", "south": "Aquarium", "west": "Office"}
},
"Aquarium": {
"name": "Aquarium",
"description": "You're in an underwater cavern, somehow you can breathe!",
"exits": {"north": "Corridor"}
},
"artificial research station": {
"description": "You're in the artificial research station. What happens here?",
"exits": {"north": "Office"}
}
}

@ -3,55 +3,19 @@
"""A simple Multi-User Dungeon (MUD) game. Players can talk to each """A simple Multi-User Dungeon (MUD) game. Players can talk to each
other, examine their surroundings and move between rooms. other, examine their surroundings and move between rooms.
Some ideas for things to try adding:
* More rooms to explore
* An 'emote' command e.g. 'emote laughs out loud' -> 'Mark laughs
out loud'
* A 'whisper' command for talking to individual players
* A 'shout' command for yelling to players in all rooms
* Items to look at in rooms e.g. 'look fireplace' -> 'You see a
roaring, glowing fire'
* Items to pick up e.g. 'take rock' -> 'You pick up the rock'
* Monsters to fight
* Loot to collect
* Saving players accounts between sessions
* A password login
* A shop from which to buy items
author: Mark Frimston - mfrimston@gmail.com author: Mark Frimston - mfrimston@gmail.com
""" """
import time import time
import json
# import the MUD server class # import the MUD server class
from mudserver import MudServer from mudserver import MudServer
with open('rooms.json', 'r') as f:
rooms = json.load(f)
# structure defining the rooms in the game. Try adding more rooms to the game! # stores the players and npcs in the game
rooms = {
"studio": {
"description": "You're in the XPUB studio. Someone is making coffee in the back.",
"exits": {"south": "neutral zone"}
},
"office": {
"description": "You're in the office. Leslie is on the phone.",
"exits": {"north": "neutral zone"}
},
"neutral zone": {
"description": "You're in the neutral zone. Some stuff happens.",
"exits": {
"south": "office",
"north": "studio",
"west" : "artificial research station"
}
},
"artificial research station": {
"description": "You're in the artificial research station. What happens here?",
"exits": {"south": "neutral zone"}
}
}
# stores the players in the game
players = {} players = {}
# start the server # start the server
@ -82,7 +46,16 @@ while True:
} }
# send the new player a prompt for their name # send the new player a prompt for their name
mud.send_message(id, "What is your 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 # go through any recently disconnected players
for id in mud.get_disconnected_players(): for id in mud.get_disconnected_players():
@ -96,7 +69,8 @@ while True:
for pid, pl in players.items(): for pid, pl in players.items():
# send each player a message to tell them about the diconnected # send each player a message to tell them about the diconnected
# player # player
mud.send_message(pid, "{} quit the game".format(players[id]["name"])) mud.send_message(pid, "\r{} quit the game".format(
players[id]["name"]))
# remove the player's entry in the player dictionary # remove the player's entry in the player dictionary
del(players[id]) del(players[id])
@ -114,22 +88,16 @@ while True:
if players[id]["name"] is None: if players[id]["name"] is None:
players[id]["name"] = command players[id]["name"] = command
# this is the room in which the game starts players[id]["room"] = "Corridor"
players[id]["room"] = "studio"
# go through all the players in the game # go through all the players in the game
for pid, pl in players.items(): for pid, pl in players.items():
# send each player a message to tell them about the new player # send each player a message to tell them about the new player
mud.send_message(pid, "{} entered the game".format( mud.send_message(pid, "{} has logged in.".format(
players[id]["name"])) players[id]["name"]))
# send the new player a welcome message # send the new player a welcome message, and a description of the starting room
mud.send_message(id, "Welcome to the game, {}. ".format( mud.send_message(id, "Welcome to textpub, " +players[id]["name"]+ ". " + rooms[players[id]["room"]]["description"] + " Type 'help' for a list of commands. Have fun!")
players[id]["name"])
+ "Type 'help' for a list of commands. Have fun!\n")
# send the new player the description of their current room
mud.send_message(id, rooms[players[id]["room"]]["description"])
# each of the possible commands is handled below. Try adding new # each of the possible commands is handled below. Try adding new
# commands to the game! # commands to the game!
@ -139,14 +107,12 @@ while True:
# send the player back the list of possible commands # send the player back the list of possible commands
mud.send_message(id, "Commands:") mud.send_message(id, "Commands:")
mud.send_message(id, " say <message> - Says something out loud, " mud.send_message(id, " say <message> - Says something out loud, "
+ "e.g. 'say Hello'") + "e.g. 'say Hello'")
mud.send_message(id, " look - Examines the " mud.send_message(id, " look - Examines the "
+ "surroundings, e.g. 'look'") + "surroundings, e.g. 'look'")
mud.send_message(id, " go <exit> - Moves through the exit " mud.send_message(id, " go <exit> - Moves through the exit "
+ "specified, e.g. 'go outside'") + "specified, e.g. 'go outside'")
mud.send_message(id, " create <exit> <new roomname> - Creates a new exit and room")
mud.send_message(id, " describe <description> - Change the description of the current room")
# 'say' command # 'say' command
elif command == "say": elif command == "say":
@ -163,10 +129,10 @@ while True:
elif command == "look": elif command == "look":
# store the player's current room # store the player's current room
current_room = rooms[players[id]["room"]] rm = rooms[players[id]["room"]]
# send the player back the description of their current room # send the player back the description of their current room
mud.send_message(id, current_room["description"]) mud.send_message(id, rm["description"])
playershere = [] playershere = []
# go through every player in the game # go through every player in the game
@ -178,14 +144,24 @@ while True:
# add their name to the list # add their name to the list
playershere.append(players[pid]["name"]) 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 # send player a message containing the list of players in the room
playershere_string = ", ".join(playershere) mud.send_message(id, "Players here: {}".format(
mud.send_message(id, f"Players here: { playershere_string }") ", ".join(playershere)))
# send player a message containing the list of exits from this room # send player a message containing the list of exits from this room
exits = ", ".join(current_room["exits"]) mud.send_message(id, "Exits are: {}".format(
mud.send_message(id, f"Exits are: { exits }") ", ".join(rm["exits"])))
# 'go' command # 'go' command
elif command == "go": elif command == "go":
@ -193,23 +169,26 @@ while True:
ex = params.lower() ex = params.lower()
# store the player's current room # store the player's current room
current_room = rooms[players[id]["room"]] rm = rooms[players[id]["room"]]
# if the specified exit is found in the room's exits list # if the specified exit is found in the room's exits list
if ex in current_room["exits"]: if ex in rm["exits"]:
# go through all the players in the game # go through all the players in the game
for pid, pl in players.items(): for pid, pl in players.items():
# if player is in the same room and isn't the player # if player is in the same room and isn't the player
# sending the command # sending the command
if players[pid]["room"] == players[id]["room"] and pid != id: if players[pid]["room"] == players[id]["room"] \
and pid != id:
# send them a message telling them that the player # send them a message telling them that the player
# left the room # left the room
mud.send_message(pid, "{} left via exit '{}'".format(players[id]["name"], ex)) 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 # update the player's current room to the one the exit leads to
players[id]["room"] = current_room["exits"][ex] players[id]["room"] = rm["exits"][ex]
current_room = rooms[players[id]["room"]] rm = rooms[players[id]["room"]]
# print(players[id]["name"] + " moved to the " + players[id]["room"])
# go through all the players in the game # go through all the players in the game
for pid, pl in players.items(): for pid, pl in players.items():
@ -224,7 +203,7 @@ while True:
players[id]["name"], ex)) players[id]["name"], ex))
# send the player a message telling them where they are now # send the player a message telling them where they are now
mud.send_message(id, "You arrive at '{}'".format( mud.send_message(id, "You have entered the {}".format(
players[id]["room"])) players[id]["room"]))
# the specified exit wasn't found in the current room # the specified exit wasn't found in the current room
@ -232,90 +211,19 @@ while True:
# send back an 'unknown exit' message # send back an 'unknown exit' message
mud.send_message(id, "Unknown exit '{}'".format(ex)) mud.send_message(id, "Unknown exit '{}'".format(ex))
# 'create' command
elif command == "create":
# store the exit or room that will be created
parameters = params.lower()
parameters_list = parameters.split()
print("[INSPECT] parameters: ", parameters_list)
if len(parameters_list) >= 1:
# store the new exit name
new_exit = parameters_list[0]
print("[INSPECT] new exit: ", new_exit)
else:
new_exit = None
if len(parameters_list) >= 2:
# store the new room name
new_room = " ".join(parameters_list[1:])
print("[INSPECT] new room: ", new_room)
else:
new_exit = None
# store the player's current room
current_room = players[id]["room"]
print("[INSPECT] current room: ", current_room)
# store information about the player's current room
current_room_dict = rooms[players[id]["room"]]
print("[INSPECT] current room dict: ", current_room_dict)
# if both the new exit and new room are given
if new_exit is not None and new_room is not None:
# send player a message when the exit already exists
if new_exit in current_room_dict["exits"]:
mud.send_message(id, "This exit already exist.")
exits = ", ".join(current_room["exits"])
# create new room
else:
print(f"[INSPECT] Make new room: { new_room }, in the direction: { new_exit }")
# add the new exit to the current room
rooms[current_room]["exits"][new_exit] = new_room
# store information about the new room
rooms[new_room] = {}
rooms[new_room]["description"] = ""
rooms[new_room]["exits"] = {}
# add the opposite exit direction to the exits of the new room
if new_exit == "west":
exit_to_add = "east"
elif new_exit == "east":
exit_to_add = "east"
if new_exit == "north":
exit_to_add = "south"
elif new_exit == "south":
exit_to_add = "north"
# store this exit to the new room
rooms[new_room]["exits"][exit_to_add] = current_room
# announce the new room to the player
mud.send_message(id, f"A new room is added: { new_room } (in the { new_exit })")
# invite the player to write a description for the room
mud.send_message(id, "The room is not described yet. When you are in the room, you can use 'describe' to add a description. For example: 'describe This is the XML! It smells a bit muffy here.'")
# warn the player when the "create" command is not used in the right way
else:
mud.send_message(id, f"Sorry you cannot create a new room in that way. Try: 'create direction roomname'")
# 'describe' command
elif command == "describe":
# store the exit or room that will be created # Item commands, to be completed
description = params.lower() # get command
print("[INSPECT] description: ", description) elif command == "get":
mud.send_message(id, "You got it")
# store the player's current room
current_room = players[id]["room"] # drop command
print("[INSPECT] current room: ", current_room) elif command == "drop":
mud.send_message(id, "You dropped it")
rooms[new_room]["description"] = description # make command
elif command == "made":
mud.send_message(id, "You made a ")
# some other, unrecognised command # some other, unrecognised command
else: else:

Loading…
Cancel
Save