On one of my pages for a previous project, I wrote about my progress in developing my IRC bot named “Yula”. At the time, I would frequently visit IRC and enjoy coding new features for others to entertain themselves with. However, I stopped visiting IRC around 2013 as the channel I would spend time in began to stagnate with fewer and fewer people logging in. Lately, I have noticed the popularity of the Discord platform growing and was intrigued by their protocol’s allowance for “bot” accounts. When I noticed that some of my old IRC buddies began to frequent various Discord servers, I ended up creating an account as well and soon began to ponder whether I could port Yula to work with Discord.
Yula was built from the ground up in C# to communicate with the IRC protocol by the means of sockets. This was possible after years of playing with the well-documented IRC protocol and figuring out the best way to structure a bot around it. Given that I do not have this experience with the Discord protocol (which is complicated by the fact that it is closed-source), I opted to utilize one of the many available unofficial APIs to develop with until I am familiar enough to write something from scratch. In early December 2016, I created a rudimentary Discord bot named “Fiona“.
One of Yula’s more memorable functions was her ability to turn the chat room into an interactive MUD-style RPG, complete with a monster spawning system, a looting/inventory system, and the newly implemented ability to travel to different maps. Given that Yula was designed in a very modular way to allow for “plugins” to provide new functionality, I began to wonder whether Yula’s “RPG.dll” plugin could be rewritten to work with Fiona; as it was, the plugin was heavily designed around the workings of IRC. I am quite happy with the solution I ultimately came up with — instead of rewriting the code to be Discord-specific, I ended up converting the RPG system into an external library that can be implemented by the means of a wrapper that passes relevant protocol events to the library. The newly termed “RPGlib” is now its own separate project and can be used by Yula, Fiona, or any other chat-based bot in the future.
To better organize development progress regarding Fiona’s implementation of RPGlib, I have created this page. Please feel free to join us at the Discord server
here <currently invite-only> to try out the RPG system and please feel free to add suggestions in the comments! If they are here, I am less likely to forget good ideas!
As with all of my bots, I tend to select a character as their “personification” and give them “personality” accordingly. Currently, Fiona is modeled after Vanilla from the Nekopara series. The features implemented as a result of RPGlib are confined to an #rpg channel on the server, while other commands/interactions are available in all server channels.
- Can be implemented by any C# project with optional protocol-specific features (e.g., Discord bots may have the option to play sound effects in the future)
- Able to load/save player data
- Leveling up system with the ability to learn skills
- Race system with the ability to affect character stats and learned skills
- Monster and Boss spawning system with customizable AI
- Looting, Inventory, Item, and Equip systems
- Ability to explore maps and travel to new areas
- Functional NPC dialogues
– 13 June 2017: Shopkeepers will now slowly destock player-sold items over time. Upon defeating an enemy, the gained experience is now expressed as a percentage rather a raw number. Created method to access individual player stats for wrapper classes. Made minor edits to strings used in level-up events. (v3.06)
– 11 June 2017: Dropped deprecated feature that used to allow players to passively gain experience by conversing in the channel. Tweaked instantiation method to allow for better configuration when implementing RPGlib. Reordered the manner in which targets are prioritized — if both a player and a mob have the same name, the mob will be targeted. (v3.02)
– 09 April 2017: Significantly restructured RPGlib to make it more flexible for use with various implementations. Cleaned up code in order to make it more efficient. (v3.01)
– 05 February 2017: Rebalanced monster stats using player feedback. Fixed a minor bug where shop NPCs got confused by items that were obtained before the database set specific prices for each item. (v2.98)
– 01 February 2017: Changed the way monster stats are calculated. Changed the way strings are handled for monsters to make it easier to make custom skill strings. Fixed improper AI entries that prevented monsters from casting buffs. Fixed a bug where monster AIs were improperly calculating the odds of a skill successfully casting. (v2.95)
– 30 January 2017: Rewrote code pertaining to player movement; certain NPCs can trigger events when players enter their maps. NPCs have the ability to check what players have equipped. Fixed a minor mistake in the character movement strings. Fixed a minor mistake in the equipment strings. (v2.91)
– 27 January 2017: NPCs now have the capability to change player spawn points. Added the ability for players to sell items to shops run by NPCs. NPCs can now restock their shops over time. Fixed a bug where items would sometimes improperly stack. Fixed a bug where NPCs would not show the prices of certain items in shops. Changed the way NPCs manage their shop inventories so that custom prices can be set for each item being sold. (v2.88)
– 22 January 2017: Added the capability for NPCs to have shop inventories that players can interact with — players can now buy items from merchants. Added a check to the message buffer to ensure that the buffer is properly emptied between messages in order to prevent message desynchronization. Rewrote a chunk of the monster spawning routine to properly handle multiple spawned monsters with the same ID. Changed how respawn cooldowns are tracked after death; cooldowns no longer mysteriously reset when monsters spawn. Players are no longer erroneously prohibited from attacking themselves inside towns. (v2.82)
– 14 January 2017: Created a new item type that allows for the summoning of monsters. Added the capability for monsters to use items. Added the capability for monsters to call for help and spawn additional monsters. Fixed a bug where monster AIs were improperly calculating the odds of a skill successfully casting. Modified default spawn times and timeout before freezing spawns due to inactivity. Changed the formula to calculate penalties and bonuses due to level differences in battles. (v2.76)
– 08 January 2017: Completely rewrote spawn system to support multiple maps; the old code predated the map system and was centered on randomly spawning level-appropriate mobs (determined by the average level of online players) for the entire channel. Maps now have independent spawn rates, boss chances, and spawn lists. Spawn timers will now freeze when channel activity is absent, rather than reset. Notifications to encourage exploration are no longer sent if there are no players on field maps. Console window now specifies where monsters spawn. Nerfed default monsters stats. Fixed a bug where certain accessories may have their effects improperly nullified after equipping a new accessory. (v2.71)
– 05 January 2017: Added the ability for NPCs to trade items with players, including the ability to define actions on trade success or failure. Infrastructure was added for NPCs to track conditional events for each player. Corrected a bug where messages were duplicated when attempting to receive an item when their inventory is full. Corrected a bug where random values may not change seeds when attacking. (v2.68)
– 04 January 2017: Added the ability for NPCs to give items to players. Changed the way players are tracked across maps to differentiate whether they are alive or dead. The !look command was completely rewritten to account for this change and is also now free from grammatical errors when listing players. Added enumerator for PvP-only maps (as opposed to normal field maps where there is both PvP and PvM). PvP is no longer permitted in towns. Added an easy multiplier for exp rates. Fixed various strings pertaining to skill descriptions and effects. (v2.63)
– 30 December 2016: Added support for NPC dialogues and player responses. In order to do this, support was in turn added to the Line Processor for messages that are sent directly to the bot. NPCs are able to support responses to a variety of different dialogue trees based on specified response IDs. NPCs were designed to stop expecting dialogue responses once the player leaves the map. !greet command is added and map strings have been changed accordingly to provide hints to its use. The ability to !greet NPCs by their proper names was also added. The character information screen now correctly lists level 1 players as having an <Unknown Race> as opposed to erroneously listing them as a “Human.” Using !move now consumes 1 stamina point. A new field map has been added. (v2.57)
– 28 December 2016: Maps now have different descriptions depending on whether the !look command is used or if the player is simply entering the map with !move. The !look command now has an allowance to list the players that are currently on the map, depending on how the map is configured. The player list was also made to be hidden in the event that the user is the only player on the map. (v2.51)
– 24 December 2016: Corrected a massive save bug that would corrupt save files after battling spawned monsters. Fixed a bug with the spawn routine where the idle timer would not reset correctly, depending on the channel being used. Removed redundant player damage routine. Altered actor classes to use proper clean-up methods. (v2.49)
– 20 December 2016: Changed the way channels are monitored. There is now an option to specify a “main” channel where RPG events occur as well as secondary channels where players can converse and use minor commands including as !bag, !char, !equip, !desc, and !help. All channels are taken into account when determining whether the system should enter idle-mode. (v2.46)
– 10 December 2016: The RPG system has officially been written to be invoked as an external library rather than a protocol-specific Object. Load/Save system was rewritten to remove redundant code. Line Processor was rewritten to better handle messages from different protocols. Fixed broken strings to correctly state which map spawned a monster. Rewrote the way time-based notifications are handled (e.g., when buffs wear off). The “Weakness” de-buff on respawn now correctly notifies you when it wears off. Fixed a bug where the “Weakness” de-buff would attempt to load missing strings under certain circumstances. Minor cosmetic changes to indicate in console that the library has been loaded. (v2.45)
Previous entries to this library’s changelog can be found on this page before it was branched off to become a separate project