Sunday, December 30, 2012

New and improved quest API?

The current concept for scripted NPCs has various shortcommings. When I want to implement scripted quests with interesting tasks, I also need to add scripting abilities to killed monsters, item pickups, map areas and lots of other stuff. All of that wouldn't hurt, but it makes programming of a complex quest awkward, because the code is in all sorts of different places. It would be better when it would be possible to implement a quest from start to finish in a single file with no or minimal editing to the entities which are part of the quest.

So I thought that it might be better to define each quest as a list of quest steps. I would have a global ScriptManager, which manages the current quest of each player character which is currently ingame. When some event happens somewhere which could be relevant to a quest of a player character, an InterMessage is created and caught by the ScriptManager. It then checks the current quest step of the player. When it is resolved, a script function attached to the QuestStep is executed. This script can either return a new QuestStep, or nothing to end the quest.

Quests are started by scripts. Usually during talking to NPCs, but I could imagine other situations which trigger quests. NPCs should gain a "quest hint" property, which consists of quest ID, a minimum level, a variable and its value. When a player fulfills these criteria, has no active quest, and hasn't completed that quest yet (which should be indicated by the value of the variable), the NPC should be highlighted.

These are possible types of quest steps:


Kill a mob spawned by a specific SpawnArea.


Own a specific number of items.


Get to a certain location.


Interact with a specific NPC.


Wait for a certain variable to change to a specific value.

Players should also be able to abort a quest at any time to start a new one. When a player does that, the quest needs to be started from the beginning.

Wednesday, December 26, 2012

Tuesday, December 18, 2012

Admin action logging

I am now logging which admin command is used by which user and when, what the arguments where and how the server replied. I only log the commands which require a special permission role, to avoid spam from normal users.

Monday, December 17, 2012

Permission roles

I added role-based permission handling for chat commands.

I got a json file "permission_roles.json" which defines the commands which can be used by each role. There is also an implicitely declared role "sysadmin" which allows to use any command.

The roles each user has are stored in the player object on the database. Direct database manipulation is currently the only way to add or remove roles (which is - as I found out -  a very dangerous method. I accidently destroyed my favorite character on the database while attempting to add a role with the update command of the mongo shell). In addition to the roles in the database, every character is also considered to have the role "everyone".

eAthena and Manaserv handle permissions per account instead of per character. I decided to use characters instead, because:
  1. I don't want GMs to irritate me and the players by doing GMing with their alt characters
  2. I am still considering to merge accounts and characters. Any functionality added to the Account class would make this more complicated.

Bug squishing

I squished lots of small bugs in the past days:

  • Current HP and MP are now saved to database, so players don't regenerate fully when logging out and in again
  • Route finding isn't even attempted when destination is non-walkable. So when a character gets stuck in a blocked area, it can't walk around while staying in the same map participation rectangle (it would be better when they couldn't get stuck there in the first place, but that's another topic)
  • Floor item stacks now have a quantity
  • Name labels don't get detached from their objects anymore (I am drawing them on the canvas again - but now I am using caching to increase text drawing performance)
  • Improved rendering performance by using insertion sort for sorting beings by draw order instead of whatever is the default sorting algorithm of the browser (the beings are only slightly out of order most of the time - in that special case insertion sort greatly outperforms all other standard sorting algorithms).
  • Fixed the problem with newly created characters not showing up until the next login.
  • Generated spell names: removed double space after level.
I also started a spreadsheet to keep track of known bugs I haven't fixed yet.