I wrote little mod to track damage stats for Age of Conan when I first started playing it. There was another damage meter at the time, but it didn't have the look and feel that I wanted. Over time I added more and more features and started several others. In the end I stoped playing Age of Conan and stoped maintaining the mod.
My core features were stable on my last release and I have watched it from a distance as people continue to download it. I can't it does not have bugs and many of my newer features are more proof of concept that show what can be done.
How did I gather dps stats?
The first big roadblock was the fact that Age of Conan did not have true mod support. It did however have a feature I could use to my advantage. AoC would generate a plain text file in realtime that contained the combat log. Every attack, heal, buff, debuff, and xp gain was recorded in that file. That one feature gave me a world of options and features that could be implemented.
Getting the correct file:
The log file was located in a sub folder within the AoC directory. During install, a registry key is set to the install path of AoC. The logs were named in such a way that an alpha sort would get me to the correct ime. On first scan of the directory, I grab the logical file and set a marker to the end of it. I start at the end of the file to exclude old stats. I assume that starting KTT is when stat collection should start.
I also add a watch on the folder for new files getting created. There are times when KTT will be running already before the logfile gets created. If I did not watch for new files it would be stuck on the old one and never collect any stats.
Processing the log:
Twice a second I reopen that file. From the marker to the end of the file, I add every plain text line into a queue. The marker is updated with the end of file and the file is closed. I had to open the file in a read only non locking stream so it did not cause issues with AoC writing to that same file. I used the queue so I could collect the data as fast as possible and get that file closed as fast as possible.
I would then work that queue with regular expression to pull out the various values and actions. I ended up with a fairly complicated regex query that did most of the work for me. I found 4 distinct sentence structures that indicate source, target, action, and a value. AoC made the combat log in sentences that were proper English that even reflected 2nd person when needed. While it sounds nice when read out loud, it creates a lot more work when writing a parser. So the regex ended up to be 4 page widths long but I didn't have to post process any of the values.
Once each line was processed into an action object, it was then placed on another queue. I used a queue her so I could multi thread the log reading/parsing away from the rest of the application. As I work this queue I would pass the object off to the plugin framework. The damage meter plugin would flatten that stats as it received them. When calculating total damage, I just add the damage on the fly so the reporting side can just report the precalculated total. (vs summing the damage every time I want to report it). I did this for any stat that I could think of.
Because I compressed the stats like this, I could keep the queue clear of actions. The point of this is my memory usage is only as wide as the number of stats I'm recording and not as large as the log file. During a large raid, the log file can grow to very large sizes very quickly. While KTT will jump in size very quickly as it sees a stat for the first time, as that stat is repeated over and over many times in the log, it will not take much additional memory.
In closing:
I may do little write ups on other features of my mod (or its potential) later. I wrote this for other mod writers. To show them that with very simple things and ideas you can do some very cool things. While I may not have described the best way to do something, it still worked very well for me. The mod is listed as KTT Damage Meter, KoS, Timers, & Sounds over at curse.com.
No comments:
Post a Comment