added some NPCs, data in JSON, visual stuff

fruitual
Stephen Kerr 1 year 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

@ -12,6 +12,34 @@ import socket
import select
import time
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):
@ -46,6 +74,39 @@ class MudServer(object):
self.buffer = buffer
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
_EVENT_NEW_PLAYER = 1
_EVENT_PLAYER_LEFT = 2
@ -111,6 +172,11 @@ class MudServer(object):
# start listening for connections on the socket
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):
"""Checks for new players, disconnected players, and new
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_disconnected()
self._check_for_messages()
self.updateNPCLocations()
# move the new events into the main events list so that they can be
# 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
# message on its own line
self._attempt_send(to, message+"\n\r")
self._attempt_send(to, message+"\r\n\r\n")
def shutdown(self):
"""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 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
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
"""
import time
import json
# import the MUD server class
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!
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
# stores the players and npcs in the game
players = {}
# start the server
@ -82,7 +46,16 @@ while True:
}
# 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
for id in mud.get_disconnected_players():
@ -96,7 +69,8 @@ while True:
for pid, pl in players.items():
# send each player a message to tell them about the diconnected
# 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
del(players[id])
@ -114,22 +88,16 @@ while True:
if players[id]["name"] is None:
players[id]["name"] = command
# this is the room in which the game starts
players[id]["room"] = "studio"
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, "{} entered the game".format(
mud.send_message(pid, "{} has logged in.".format(
players[id]["name"]))
# send the new player a welcome message
mud.send_message(id, "Welcome to the game, {}. ".format(
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"])
# 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!
@ -139,14 +107,12 @@ while True:
# send the player back the list of possible 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'")
mud.send_message(id, " look - Examines the "
mud.send_message(id, " look - Examines the "
+ "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'")
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
elif command == "say":
@ -163,10 +129,10 @@ while True:
elif command == "look":
# 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
mud.send_message(id, current_room["description"])
mud.send_message(id, rm["description"])
playershere = []
# go through every player in the game
@ -178,14 +144,24 @@ while True:
# 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
playershere_string = ", ".join(playershere)
mud.send_message(id, f"Players here: { playershere_string }")
mud.send_message(id, "Players here: {}".format(
", ".join(playershere)))
# send player a message containing the list of exits from this room
exits = ", ".join(current_room["exits"])
mud.send_message(id, f"Exits are: { exits }")
mud.send_message(id, "Exits are: {}".format(
", ".join(rm["exits"])))
# 'go' command
elif command == "go":
@ -193,23 +169,26 @@ while True:
ex = params.lower()
# 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 ex in current_room["exits"]:
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:
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))
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"] = current_room["exits"][ex]
current_room = rooms[players[id]["room"]]
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():
@ -224,7 +203,7 @@ while True:
players[id]["name"], ex))
# 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"]))
# the specified exit wasn't found in the current room
@ -232,90 +211,19 @@ while True:
# send back an 'unknown exit' message
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
description = params.lower()
print("[INSPECT] description: ", description)
# store the player's current room
current_room = players[id]["room"]
print("[INSPECT] current room: ", current_room)
# 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")
rooms[new_room]["description"] = description
# make command
elif command == "made":
mud.send_message(id, "You made a ")
# some other, unrecognised command
else:

Loading…
Cancel
Save