What am I looking at?
See below for a summary of currently implemented features and functionality. All areas listed below have been tested to a reasonable degree. Keep in mind the server has never been exposed to to a truly multi-user audience and pretty much all testing was accomplished via running multiple clients from a single machine. As much as I have managed to tackle all the crashes and game-breaking bugs I could find, it is probably safe to assume more and more will surface as the code is (hopefully) exposed to more than one pair of eyes (and that's a good thing!).
Each section describes one of the key functionalities and includes some TODO ideas for future development and improvement.
Network connectivity
Server communicates with its clients via standard Telnet protocol, dumengine-generic branch is compatible with MU* clients which support standard 256 ANSI color codes. All testing so far was done using Mudlet.
Rooms
The idea of distinct game areas (rooms) has been implemented. Players can move between the areas via appropriately named exits using a go command, each one of them leading to another room.
Rooms have unique IDs (in the $rid=X$ format) and non-unique room names. It is possible for multiple rooms to have the same name (imagine a really long corridor consisting of a number of unique rooms, each one of them named "The Corridor").
## TODO ideas: ## * Room definitions are currently hard-coded in server ## code (using a nested Python dictionary). It would make ## sense to shift this into a database or separate files to ## be loaded on server startup.
Chat
Players have the ability to send messages to others in the same room via the say command.
## TODO ideas: ## * 'whisper' functionality to send a message to individual ## player in the same room ## * 'tell' functionality to send a message to individual ## player in the game (not necessarily in the same area) ## * 'shout' functionality for a message to be visible in ## e.g. all adjacent rooms
Database
Server has been developed to work in conjunction with a database for the purpose of storing player information, NPC details, Items details and Environment Actor details (see further down this document for more details on those).
Database is also used to achieve player state persistence (also see further down).
Currently a standard MySQL database is used, running on the same machines as the server itself. There is no reason it couldn't be split and kept on a separate host.
Following tables are implemented and used by the server:
tbl_Players - Information existing, registered players (not online players)
tbl_NPC - Details of all NPCs
tbl_Items - Database of all items in the game
tbl_Env - Details of all environment actors
Important! At the moment, user passwords are held in the database in plain text. No mechanism has been implemented to hide/obscure the passwords.
The Player and Character Sheet
Every player in the game is represented by a dictionary of values in server's memory. Some of those values are pulled from the database when a player logs in, others are dynamic and exist only in memory per each player session.
Value | Description | In DB? |
---|---|---|
authenticated | Marks if the player connected to the server has successfully authenticated by providing a valid password - which would mean he is currently in the game world. | No |
room | Room ID the player is currently in | Yes |
lvl | Current Player level | Yes |
exp | Amount of experience points Player has | Yes |
str | Strength stat | Yes |
per | Perception stat | Yes |
endu | Endurance stat | Yes |
cha | Charisma stat | Yes |
int | Inteligence stat | Yes |
agi | Agility stat | Yes |
luc | Luck stat | Yes |
cred | Amount of credits (money, gold etc.) players has in posession | Yes |
inv | Player inventory - this is a comma delimited string containing item IDs | Yes |
clo_head | Head cloting item | Yes |
clo_larm | Left Arm clothing item | Yes |
clo_rarm | Right Arm clothing item | Yes |
clo_lhand | Left Hand clothing item | Yes |
clo_rhand | Right Hand clothing item | Yes |
clo_chest | Chest clothing item | Yes |
clo_lleg | Left Leg clothing item | Yes |
clo_rleg | Right Leg clothing item | Yes |
clo_feet | Feet clothing item | Yes |
imp_head | Head implant | Yes |
imp_larm | Left Arm implant | Yes |
imp_rarm | Right Arm implant | Yes |
imp_lhand | Left Hand implant | Yes |
imp_rhand | Right Hand implant | Yes |
imp_chest | Chest implant | Yes |
imp_lleg | Left Leg implant | Yes |
imp_rleg | Right Leg implant | Yes |
imp_feet | Feet implant | Yes |
hp | Player health points | Yes |
charge | Player charge (think 'mana') | Yes |
isInCombat | Player is in combat flag | No |
lastCombatAction | Last time player made a combat action | No |
isAttackable | Flags whether it is possible to attack a player | No |
corpseTTL | Time in seconds before player corpse disappears from a room | No |
Player Statistics
Player stats are at the moment heavily influenced by the S.P.E.C.I.A.L stat system known from Fallout games (Fallout 2 FTW). Stat system is very rudimentary without too much thought put into it. Focus was around developing a working framework with the view of modifying the stat system accordingly later in the process.
At the moment only STR and AGI stats are used in the code to calculate combat factors (how often player attacks and how hard it hits).
Clothing and Implants
A very basic character clothing system has been implemented in the database. There are 9 clothing slots and 9 implant slots (Anarchy Online anyone?) - see below. Those are meant to be filled by item IDs and offer modifications to calculations that govern various player actions.
## TODO ideas: ## * A LOT can be done I guess. Perhaps a re-think of the entire approach ## to make it as versatile and adaptable as possible. From the more ## practical things I can think of at the moment: ## * Additional set of slots for Equipment (weapons, gadgets, trinkets, you name it) ## * ??
Combat and Player death
Players can attack other players and non-player characters via the attack command. Attacking an entity initiates the attack cycle in which player attempts to his the target periodically. NPCs will automatically retaliate any attacks and fall into their own attack loops targeting whoever was the first to attack them.
## TODO ideas: ## * An idea of Aggro, where NPCs change their target ## based on whoever deals the most damage ## * Some kind of 'stop' command, which would ## stop the player attack cycle, effectively ceasing ## attacking the target ## * Similarly for an NPC - implementing some logic ## to have the NPC stop attacking on certain conditions ## (e.g. the player it was attacking has left the room)
When player's Hit Points reach 0, it receives a "Oh dear, you have died!" message (Runescape anyone?). Upon death, player is transported to a specified room and a corpse is spawned at the place of death. For the purpose of this release, a room ID 666 called 'The Void' has been included. Player does not loose any belongings, but the HP is reduced to 4. Keep in mind this is completely subject to change, those basic behaviors have been implemented as a proof of concept type of thing.
Corpses
When a player or an NPC dies, a corpse is spawned in the room death took place. Each corpse has a TTL in seconds (Time To Live) - the amount of seconds before corpse disappears from the world. Those values are currently hard-coded in 'players' and 'npsc' dictionaries within server code.
## TODO ideas: ## * Corpse looting ## * Looting permissions
NPCs
Each NPC is represented by the following dictionary within server code, with information being pulled from the database on server boot.
Value | Description | In DB? |
---|---|---|
name | NPC's name | Yes |
room | Room ID the NPC is currently in | Yes |
lvl | Current NPC level | Yes |
exp | Amount of experience points NPC has | Yes |
str | Strength stat | Yes |
per | Perception stat | Yes |
endu | Endurance stat | Yes |
cha | Charisma stat | Yes |
int | Inteligence stat | Yes |
agi | Agility stat | Yes |
luc | Luck stat | Yes |
cred | Amount of credits (money, gold etc.) NPC has in possession | Yes |
inv | NPC inventory - this is a comma delimited string containing item IDs | Yes |
isAttackable | Signifies whether a player is be able to attack this NPC | Yes |
isStealable | Not in use / TODO - Signifies whether it is possible to steal from this NPC | Yes |
isKillable | Not in use / TODO - Signifies if an NPC can die (e.g. "Guard is unconscious" rather than "Guard has been killed") | Yes |
isAggressive | Not in use / TODO - Signifies if an NPC is aggressive (e.g. attacks players when they walk in the room) | Yes |
vocabulary | NPC's vocabulary - it's a string of phrases delimited by a pipe ('|'). Every NPC will speak a random phrase from this list when it is his time to talk. | Yes |
talkDelay | Number of seconds of delay between speaking a random phrase from NPC's vocabulary | Yes |
lookDescription | Not in use / TODO - description of an NPC (e.g. look Guard will result in displaying description stored there) | Yes |
timeTalked | Last time an NPC talked, gets updated every time an NPC talks, and is used for the "is it time to talk yet?" calculation | No |
clo_head | Head clothing item | Yes |
clo_larm | Left Arm clothing item | Yes |
clo_rarm | Right Arm clothing item | Yes |
clo_lhand | Left Hand clothing item | Yes |
clo_rhand | Right Hand clothing item | Yes |
clo_chest | Chest clothing item | Yes |
clo_lleg | Left Leg clothing item | Yes |
clo_rleg | Right Leg clothing item | Yes |
clo_feet | Feet clothing item | Yes |
imp_head | Head implant | Yes |
imp_larm | Left Arm implant | Yes |
imp_rarm | Right Arm implant | Yes |
imp_lhand | Left Hand implant | Yes |
imp_rhand | Right Hand implant | Yes |
imp_chest | Chest implant | Yes |
imp_lleg | Left Leg implant | Yes |
imp_rleg | Right Leg implant | Yes |
imp_feet | Feet implant | Yes |
hp | Health points | Yes |
charge | Charge (think 'mana') | Yes |
isInCombat | "NPC is in combat" flag | No |
lastCombatAction | Last time NPC made a combat action | No |
lastRoom | Not in Use (99% sure on this one at the time of writing) | No |
corpseTTL | Time in seconds before player corpse disappears from a room | No |
respawn | Number of seconds before an NPC respawns | Yes |
whenDied | Gets updated when NPC dies, used for handling respawns | No |
## TODO ideas: ## * Move the corpseTTL attribute into a database table, as it is currently hardcoded in server code
Items
All items are stored in the Items dictionary with following values, all pulled from the DB:
Value | Description | In DB? |
---|---|---|
name | Item name | Yes |
long_description | Not in use / TODO - Longer item description | Yes |
short_description | Not in use / TODO - Short item description | Yes |
clo_head | Not in use / TODO - Is it equippable in this slot? | Yes |
clo_larm | Not in use / TODO - Is it equippable in this slot? | Yes |
clo_rarm | Not in use / TODO - Is it equippable in this slot? | Yes |
clo_lhand | Not in use / TODO - Is it equippable in this slot? | Yes |
clo_rhand | Not in use / TODO - Is it equippable in this slot? | Yes |
clo_chest | Not in use / TODO - Is it equippable in this slot? | Yes |
clo_lleg | Not in use / TODO - Is it equippable in this slot? | Yes |
clo_rleg | Not in use / TODO - Is it equippable in this slot? | Yes |
clo_feet | Not in use / TODO - Is it equippable in this slot? | Yes |
imp_head | Not in use / TODO - Is it equippable in this slot? | Yes |
imp_larm | Not in use / TODO - Is it equippable in this slot? | Yes |
imp_rarm | Not in use / TODO - Is it equippable in this slot? | Yes |
imp_lhand | Not in use / TODO - Is it equippable in this slot? | Yes |
imp_rhand | Not in use / TODO - Is it equippable in this slot? | Yes |
imp_chest | Not in use / TODO - Is it equippable in this slot? | Yes |
imp_lleg | Not in use / TODO - Is it equippable in this slot? | Yes |
imp_rleg | Not in use / TODO - Is it equippable in this slot? | Yes |
imp_feet | Not in use / TODO - Is it equippable in this slot? | Yes |
mod_str | Not in use / TODO - Modifier to the STR stat | Yes |
mod_per | Not in use / TODO - Modifier to the PER stat | Yes |
mod_end | Not in use / TODO - Modifier to the END stat | Yes |
mod_cha | Not in use / TODO - Modifier to the CHA stat | Yes |
mod_int | Not in use / TODO - Modifier to the INT stat | Yes |
mod_agi | Not in use / TODO - Modifier to the AGI stat | Yes |
mod_luc | Not in use / TODO - Modifier to the LUC stat | Yes |
weight | Not in use / TODO - Item weight | Yes |
article | Noun article (e.g. AN Empty Bottle, A Journal Page) | Yes |
Environment Actors
I have implemented a subsystem for environmental actors which can be placed in rooms. The principle is simple and similar to an NPC being able to speak random phrases from a vocabulary at set time intervals. Rather than NPC however, the Environment Actors are things like a flickering computer screen, or a leaking bathroom tap. Environment actors send messages to players in the room at set time intervals e.g.
[Bathroom Tap]: <drip> <drip>
Or
[Computer Screen]: The animation freezes briefly before returning to normal in what appeared to be a brief glitch in the broadcast.
All environment actors are stored in a database (see all attributes below) and loaded into memory on server boot.
Value | Description | In DB? |
---|---|---|
name | Actor name | Yes |
room | Room the actor is in | Yes |
vocabulary | Vocabulary of phrases delimited by a pipe ('|') | Yes |
talkDelay | Delay in seconds between seding a random phrase to the room | Yes |
timeTalked | Las time a phrase was sent | No |
lastSaid | Not in use / TODO - Last phrase used, planned to help avoid sending the same message in succession | No |
## TODO ideas: ## * Implement the 'lastSaid' attribute to avoid duplicate message sent in succession
Available commands
- say <message> - Say something out loud, send the message to all players currently in the same room.
- look - Examines the surroundings, displays description of player's current room and available exits. Additionally lists other players, NPCs and Items currently in the room.
- go <exit> - Moves to another room via exit indicated.
- attack <target> - Attack indicated PC or NPC target.
- check inventory - Check player inventory.
- take <item> - Pick up an item and place it in your inventory.
- drop <item> - Drop an item from player inventory on the floor.
Player accounts and authentication
Player can connect to the server using a combination of player name and password. Following exchange occurs when a connection is made:
What is your username?
<name>
Hi <name>
What is your password?
<password>
Welcome to the game, <name>.
WARNING: All passwords are stored in plain text and changing it something remotely close to anything described as 'secure' is a huge TODO.
ANSI color support
When sending messages to clients via the send_message() function, it is possible to send ANSI color formatted messages. ANSI compatible mud client will be able to process this and display multi-color text and background as well as underlined and bold text.
It is possible to use one of the following tags to mark a change in text format:
- <fXXX> - Text foreground color, where XXX is an integer between 0 and 255
- <bXXX> - Text background color, where XXX is an integer between 0 and 255
- <b> - Bold text
- <u> - Underlined text
- <r> - Resets text formatting back to terminal default
For example, sending the following message to a client:
send_message(id, '<f134><b42>Hello<r> <u><b><f15>World<r>!')
Supported colors and corresponding integers to be used with <fXXX> and <bXXX>: