PDA

View Full Version : Achievement Tracker (5E)



jkeller
February 11th, 2026, 02:37
https://forge.fantasygrounds.com/shop/items/2838/view

This 5E extension will detect and track "achievements". They are added to a new "Stats" tab on the character sheet.

This is very much a work in progress. This is a complex extension. I've tested it with multiple groups for several weeks, but it's likely there are still bugs (please report them). There is an option disable the extension (it's a toggle box), but worst case you can restart your server after unselecting it.

Comments, bug reports, and suggestions are appreciated! (in this thread, or in the discord in my sig)

- It's event-driven, so most achievements are awarded as they are "earned".
- The extension doesn't try to retroactively determine which achievements a character has.
- The DM can use the option's "Scan" button (or the "/ach scan" command in the chat window) to perform a in-depth check for some static achievements, such as playing on certain dates, or matching certain fantasy/historical characters. The scan is automatically done when the session ends.
- A few achievements (like killing a dragon) are earned by everyone in the party when they happen.

Some notes on scope:
- Some achievements are "within a session", which means that the triggers will be tracked during the session, but flushed when the host exits.
- Some achievements are "within an encounter". An encounter starts when a PC rolls init (unless it already started within the last 10 minutes). The encounter ends when the last foe is killed, or the party rests. It does not end when the session ends (since an encounter can span multiple sessions).

The extension works best if you set a DC for skill checks. You can do this on the Party Sheet, but a better way (if you want the players to roll, and to select specific players), is to use the wonderful Requested Rolls extension.

In general, using FG's features helps trigger achievements. For example:

actually using powers/feats/etc instead of just telling the DM
distributing loot via the Party Sheet
using Shift for Opportunity attacks


The Achievement Tracker doesn't depend on any other extensions, but some may help it check for certain triggers, such as:

Aura Effect (https://forge.fantasygrounds.com/shop/items/32/view)
Fishing Fun (https://forge.fantasygrounds.com/shop/items/2836/view)
Pets (https://forge.fantasygrounds.com/shop/items/1960/view)
Requested Rolls (https://forge.fantasygrounds.com/shop/items/273/view)
Undead Fortitude (https://forge.fantasygrounds.com/shop/items/1215/view)


Other extension developers can add their own achievements by calling this function:


function triggerAchievement(nodeChar, sAchievement)
if nodeChar and sAchievement then
local nodeAchv = nodeChar.createChild("achvToAdd", "string");
if nodeAchv then
DB.setValue(nodeChar, "achvToAdd", "string", sAchievement);
end
end
end

The format of the sAchievement must be: "Some Name; how to earn". For example:

triggerAchievement(nodeChar, "Rocks Fall, Everyone Dies; cast Meteor Swarm on your own party");

If you need to add more than one in a short time frame, you can queue them:


function awardAchievementTo(nodeChar, sAchievement)
if nodeChar and sAchievement then
local nodeQueue = nodeChar.createChild("achievement_queue");
if nodeQueue then
local child = nodeQueue.createChild({some unique ID}, "string");
child.setValue(sAchievement);
end
end
end

The queued nodes will be deleted after they are processed.

Tempered7
February 11th, 2026, 07:11
Yay, It's finally here!
I love what you do with extensions for video game/MMO feel. It brings me back to Classic WoW times. :)

Im probably gonna die trying to get that dragon achievement solo, haha.

Would you consider adding some fishing achievements to it maybe some time later?

I've come back with some feedback: EXTRA thank you for the Export and STATS options. This is more fun than MMOs!

I think I found 2 problems:

1. Items added in Char-gen Triggers the Loot Achievement. Assuming its meant for looting an enemy ingame.

66561

2. Is Rush A Cleric - Get 1 INIT bugged? Eldariel [the cleric] rolled for 17 on Init but got the achievement.

66562

jkeller
February 13th, 2026, 21:25
Would you consider adding some fishing achievements to it maybe some time later?

Definitely! Now that the Fishing Fun extension is done, they're on the short list.

Thanks for reporting the bugs; I'll take a look. I'm sure there are going to be quite few issues (hopefully nothing serious), at least for a while. It's very hard to test. :)

Tempered7
February 13th, 2026, 22:14
I thank you for the love you put on these extensions and making 'em free! Now I have extra motivation to play instead of writing. xD

So far, I've gained around 10-15 achivs and only those two were buggy.
As I gain achivements with different chars, Im checking them and exporting the txt files so I hope it will help you in the future.

jkeller
February 13th, 2026, 22:21
1. Items added in Char-gen Triggers the Loot Achievement. Assuming its meant for looting an enemy ingame.
2. Is Rush A Cleric - Get 1 INIT bugged? Eldariel [the cleric] rolled for 17 on Init but got the achievement.

Both should be fixed now. There's no great way to tell if a character is being created, so I restricted most loot achievements to only apply to characters who are on the Combat Tracker, and at least level 2.

jkeller
February 14th, 2026, 19:41
Added a simple way for other extension developers to add their own achievements.

Just add and call this function:


function triggerAchievement(nodeChar, sAchievement)
if nodeChar and sAchievement then
local nodeAchv = nodeChar.createChild("achvToAdd", "string");
if nodeAchv then
DB.setValue(nodeChar, "achvToAdd", "string", sAchievement);
end
end
end

The format of the sAchievement must be: "Some Name; how to earn". For example:

triggerAchievement(nodeChar, "Rocks Fall, Everyone Dies; cast Meteor Swarm on your own party");

Chivalrous1
February 15th, 2026, 18:11
Is there a list of the achievements? Is there a way to add achievements?

jkeller
February 15th, 2026, 18:59
Unfortunately, there are way too many to post here (approaching 1,000 now, with more being added when I have time).

I really don't want to post some kind of checklist that would make completionists feel obligated to try and get them all, since some are just incredibly unlikely. Also, I don't want to spoil the surprise :) But if you have any specific questions, I'll try to answer them.

If anyone has ideas for achievements, I'm happy to try to support them. Just be aware that anything FG doesn't know about probably can't be supported.

The hard part is detecting when the achievement is earned. Some are almost impossible - for example, I have a bunch of ideas for various polymorph/transformation/wild-shape achievements, but FG doesn't really have any way for me to detect when that happens (though I guess an extension like One-Click-Druid could do it for some cases).

As noted in my previous post, it should be easy for other extension developers to add their own. For example the Fishing Fun extension adds several fishing achievements (which this extension is completely unaware of).

graphil
February 16th, 2026, 08:36
I tried this in our game yesterday. A good bit of fun.
A few bits of feedback. It did trigger a few of the rolling 20's or 1's when players were rolling on the tower giving the game away somewhat. Might want to exclude tower rolls.
I have monsters on the CT that are hidden ready for when they are needed. In a combat they closed the door and only saw 1 of the 8 that were in hiding. All 8 appeared on the stats. These are getting included in the encounters NPCs even when they never became unhidden.
Similarly there was an achievement triggered for 10+ foes (Leeroy jenkins). However that was counting hidden ones on the CT so shouldn't really have counted.
I have friendly NPCs like dancing lights for the spell. These are getting included in the stats multiple times since they are there most combats.
I have NPC flavours installed so each monster is uniquely named rather than 1,2,3, etc. This is going to make the encountered list very long over time. Ideally would be good if they are collapsed somehow.

There was an error getting thrown when NPC's were rolling attacks. Didn't have time to capture it though as was mid combat. Will try another time if I can.

Tempered7
February 16th, 2026, 13:09
There was an error getting thrown when NPC's were rolling attacks. Didn't have time to capture it though as was mid combat. Will try another time if I can.

I'd like to test this one.
Could you tell me to steps to recreate?

graphil
February 16th, 2026, 13:14
Sorry, outside of it being a straight attack from an NPC I wasn't focusing on what was happening as was running the combat at the time.

graphil
February 16th, 2026, 13:24
Actually, I think I might know what it is.
The enemy was attacking a familiar that was set up using the pets extension. I bet it was throwing an error trying to record info for the familiar but didn't have a place to put it.

jkeller
February 16th, 2026, 14:23
Thanks for the feedback! I'll see if I can ignore hidden rolls and NPCs.

Tempered7
February 17th, 2026, 22:44
Ah, I overslept on this one but I guess it is being worked on now.

EDIT: I just tested it with Pets ext and Achivements Trackers along with many others.

1. Gave an owl to a PC
2. Placed the owl, the PC, and a bandit on a map
3. Bandit attacked the owl
4. No errors.

jkeller
February 17th, 2026, 22:54
Yeah, ongoing. I've modified it so that hidden rolls won't broadcast achievements. The achievements are still earned (and added to the Stats tab), and the chime does sound, but no message is sent. I don't want to disable them completely (since some tables may use the tower a lot), but this seems like a good compromise. I'm still testing.

The encounter issues are a bit trickier. My current thinking is that hidden NPCs should not be added to the encounter list, but once visible, they should be (identified or not).

The flavor names are also an issue. If you use my Flavorful Names extension, it won't be an issue as it uses the original name (that extension adds the original name as an effect on the creature). I'm not sure yet how I'll deal with the NPC Flavor extension that graphil mentioned; hopefully there's a way to get the original name.

Tempered7
February 17th, 2026, 23:23
If you cant get the original name, can you get the modified name?

jkeller
February 17th, 2026, 23:50
If you cant get the original name, can you get the modified name?

Yep, but I think that's the problem - there will just end with too many in the Encountered list.

Tempered7
February 18th, 2026, 00:07
If I understood it correctly, gathering too many variable names is the problem?

So, I was thinking. Can the " () " parantheses in the flavor names be used to grab them?
As in, instead of going for the names, you target for the parantheses after the name to grab them all at once?

Or did I misunderstand?

jkeller
February 18th, 2026, 00:14
Getting the names from the Combat Tracker should be no trouble. I think the issue is just that with every NPC encountered having an essentially unique name (due to the flavoring), the list of encountered creatures (which the extension tracks) will get too cluttered.

I need to grab the NPC Flavor extension and test with it - it might be easy to address (assuming I can get the original names); i just don't know yet.

I assume it already deals with the built-in unique suffixes (Goblin 1, Goblin 2, etc), but I don't recall for sure.

graphil
February 18th, 2026, 07:49
Maybe just include an option to only store types in the list since that is nice and clean? So then the users can decide if they want all the unique names or not.

jkeller
February 18th, 2026, 14:48
Yeah, I'll think about it more. I'm not listing them to provide that info; I'm keeping them to trigger certain achievements. But I agree they will get cluttered. I might be able to add a collapse button, or even simply hide them (but keep the list in the database). That's true of all the other stats too (saves, skill checks, spells etc) - I just need them to trigger achievements. Many achievements don't need much history (just the current session or battle), but many others need the history.

Either way, I don't what the flavored names, just the standard ones (no achievements are related to the flavored names).

jkeller
February 18th, 2026, 22:09
I found how to get the original name (for NPCs flavored by the NPC Flavor extension).

This version should not show achievements for hidden rolls, and should ignore hidden NPCs, and should use the unflavored name. Hopefully this will reduce the encountered clutter.

graphil
February 23rd, 2026, 07:14
I got what I think was the same error again. Was user casting shocking grasp on animated sword and killing it. Saved the log this time so hopefully it will help.

[2/22/2026 3:01:50 PM] [AT] Damage.applyDamageDecorator (before apply): damage
[2/22/2026 3:01:50 PM] s'ActorManager.getTypeAndNode/getTypeAndNodeName - DEPRECATED - 2025-04-22 - Use ActorManager.isPC/isRecordType/getCreatureNode/getCTNode'
[2/22/2026 3:01:50 PM] s'ActorManager.getTypeAndNode/getTypeAndNodeName - DEPRECATED - 2025-04-22 - Use ActorManager.isPC/isRecordType/getCreatureNode/getCTNode'
[2/22/2026 3:01:50 PM] [AT] Damage.applyDamageDecorator (after apply): damage
[2/22/2026 3:01:50 PM] [AT] Damage.doDamage: Ryaen von der Claque damaged Flying Sword
[2/22/2026 3:01:50 PM] [AT] [Damage.damageNPC] Flying Sword; HP: 30; Wounds: 30
[2/22/2026 3:01:50 PM] [AT] AT_Defeat.killNPC killerCS: userdata: 000001C3EE67E6E8; source: Ryaen von der Claque
[2/22/2026 3:01:50 PM] GM Ryaen von der Claque unlocked achievement: I Am The Storm (kill an enemy with Lightning)
[2/22/2026 3:01:50 PM] [AT] AT_Events.setStatQty missing/invalid actor for: Killed with Lightning
[2/22/2026 3:01:50 PM]
stack traceback:
[string "Achievement Tracker:scripts/utils.lua"]:44: in function 'resolveActor'
[string "Achievement Tracker:scripts/events.lua"]:157: in function 'setStatQty'
[string "Achievement Tracker:scripts/defeat.lua"]:138: in function 'scanDamageType'
[string "Achievement Tracker:scripts/defeat.lua"]:13: in function 'killNPC'
[string "Achievement Tracker:scripts/damage.lua"]:197: in function 'damageNPC'
[string "Achievement Tracker:scripts/damage.lua"]:153: in function 'doDamage'
[string "Achievement Tracker:scripts/damage.lua"]:90: in function 'scanDamage'
[string "Achievement Tracker:scripts/damage.lua"]:45: in function 'applyDamage'
[string "5E:scripts/manager_action_damage.lua"]:26: in function 'fHandler'
[string "CoreRPG:scripts/manager_oob.lua"]:26: in function <[string "CoreRPG:scripts/manager_oob.lua"]:18>
[2/22/2026 3:01:50 PM] [ERROR] Handler error: [string "Achievement Tracker:scripts/defeat.lua"]:138: attempt to compare number with nil

jkeller
February 23rd, 2026, 15:16
Thanks, that helped - it should be fixed now.

jkeller
February 28th, 2026, 14:22
I updated it to use the new getPostRollHandler; it should be less likely to conflict with other extensions now.

Atreides Ghola
March 16th, 2026, 14:33
Hello!

Found a bug. Latest version of FGVTT, 5.5e 2024 ruleset.

With this extension enabled in a clean campaign with no other extensions, this extension prevents untargeted attack rolls from being reported in the chat. It does recognize them (popped an achievement for rolling a crit), but the result of untargeted attacks doesn't show. Targeted attacks show just fine.

Thanks

jkeller
March 16th, 2026, 15:51
Thanks, I'll check it out asap.

jkeller
March 16th, 2026, 17:36
Hello!

Found a bug. Latest version of FGVTT, 5.5e 2024 ruleset.

With this extension enabled in a clean campaign with no other extensions, this extension prevents untargeted attack rolls from being reported in the chat. It does recognize them (popped an achievement for rolling a crit), but the result of untargeted attacks doesn't show. Targeted attacks show just fine.

Thanks

Should be fixed now, thanks for reporting it!

cdjensen99
March 18th, 2026, 16:58
Hello, I just got this extension and so far it looks good, with one thing. Maybe I am doing something wrong. I put a creature on the combat tracker and then I have a character attack it until it is dead so that I can see what all is happening. However Nothing is populating in the Encounters NPC section, all the rest popular just fine. It is the only extension active. So I am not sure if I am missing a step.

Do you need to have a Map with everything on it?

jkeller
March 18th, 2026, 19:43
Yeah, encounters could be better. You don't need a map. But, to avoid spoilers, encounters are not logged unless the NPC is visible (in the combat tracker).

Making it visible should cause it to be added under "ENCOUNTERED NPCs" on the Stats tab.

There is code that gets triggered when an NPC damages a PC, etc, but I think those triggers need work.

cdjensen99
March 18th, 2026, 20:18
Thanks I will do that.

EDIT: That did the trick, Thanks

charros
March 20th, 2026, 03:44
Hello,

My players and I love this extension as this is just a great fun to have durin our sessions, so thank you for creating it. I do have a extension Strength of the Grave and it is giving a error when it is procs:

66846

jkeller
March 20th, 2026, 18:44
Should be fixed now, thanks for reporting!

charros
April 27th, 2026, 05:31
Hey there! Just got another error as I want to report it!67217

jkeller
April 27th, 2026, 13:25
Thanks! should be fixed now

jkeller
May 23rd, 2026, 22:02
It looks like the recent FG update changed how this extension needs to hook-to many different triggers. It doesn't cause any errors, but it also doesn't work. I'm updating as fast as I can, but until I do, I recommend not loading this (or at least disabling it in the options). It will probably be a couple weeks; there are a lot of hooks.

jkeller
June 7th, 2026, 20:00
I think it should be working pretty well again. Let me know if you notice any issues (or if you have an idea for an achievement).

Atreides Ghola
June 23rd, 2026, 14:52
Sorry to be hammering you with bugs today - In my Sunday night game and testing today, this extension is preventing healing from being applied to actors in a number of different ways.

Casting a cure wounds or similar spell with tokens targeted - no healing is applied.
Dragging and dropping healing from a character sheet to a token - no healing is applied.
Dragging and dropping a heal from the Chat to a token - no healing is applied.
The operator 'steal' is not being respected - So, something like DMG: 4d6 necrotic, steal as an effect on a CT entry will roll the damage, but will not apply the healing to the CT entry with the effect. (Blood Fury Tattoo).

Another really cool extension - but not being able to heal is a deal-breaker, unfortunately.

jkeller
June 23rd, 2026, 15:28
Thanks for the detailed report! I should be able to fix those fairly quickly.

jkeller
June 23rd, 2026, 15:39
Casting a cure wounds or similar spell with tokens targeted - no healing is applied.
Dragging and dropping healing from a character sheet to a token - no healing is applied.


So far, I can't duplicate the bug. Do you see any possibly related messages in your console? You may have to use /console to open it.

For example, I see:


[6/23/2026 10:33:49 AM] [AT] Power.checkPower Eowyn; power: Cure Wounds; school: evocation
[6/23/2026 10:33:49 AM] [AT] Cast.scanSpell Eowyn: Cure Wounds (1)
[6/23/2026 10:33:49 AM] [AT] Cast.scanBattleSpells: Eowyn
[6/23/2026 10:33:53 AM] [AT] Roll.postRoll type: heal; source: Eowyn
[6/23/2026 10:33:53 AM] [AT] Roll.postRoll [heal]: [HEAL] Cure Wounds [MOD: WIS (1)]
[6/23/2026 10:33:53 AM] [AT] Roll.dispatchRoll: Eowyn heal - [HEAL] Cure Wounds [MOD: WIS (1)]
[6/23/2026 10:33:53 AM] [AT] Roll.annotateRoll: [HEAL] Cure Wounds [MOD: WIS (1)]; # = 1
[6/23/2026 10:33:53 AM] [AT] Roll.scanRoll: Eowyn
[6/23/2026 10:33:53 AM] [AT] [AT_Damage.applyDamageDecorator (before apply)] heal


Are you using any other extensions that might be interacting with healing/damge rolls?

Also just in case - have you updated recently? I do recall a bug where the code was checking the type for "heal" (which missed "recovery" healing from short rests), but that was fixed by checking for "not damage":

if rRoll.sType ~= "damage" then return; end -- may be "heal" or "recovery"

jkeller
June 23rd, 2026, 15:50
The operator 'steal' is not being respected - So, something like DMG: 4d6 necrotic, steal as an effect on a CT entry will roll the damage, but will not apply the healing to the CT entry with the effect. (Blood Fury Tattoo).

Trying to duplicate this one now. I have TCoE activated, and I have a PC attuned to that item. Where does the "steal" show up? Is that a damage type?

Atreides Ghola
June 23rd, 2026, 16:02
So far, I can't duplicate the bug. Do you see any possibly related messages in your console? You may have to use /console to open it.

For example, I see:


[6/23/2026 10:33:49 AM] [AT] Power.checkPower Eowyn; power: Cure Wounds; school: evocation
[6/23/2026 10:33:49 AM] [AT] Cast.scanSpell Eowyn: Cure Wounds (1)
[6/23/2026 10:33:49 AM] [AT] Cast.scanBattleSpells: Eowyn
[6/23/2026 10:33:53 AM] [AT] Roll.postRoll type: heal; source: Eowyn
[6/23/2026 10:33:53 AM] [AT] Roll.postRoll [heal]: [HEAL] Cure Wounds [MOD: WIS (1)]
[6/23/2026 10:33:53 AM] [AT] Roll.dispatchRoll: Eowyn heal - [HEAL] Cure Wounds [MOD: WIS (1)]
[6/23/2026 10:33:53 AM] [AT] Roll.annotateRoll: [HEAL] Cure Wounds [MOD: WIS (1)]; # = 1
[6/23/2026 10:33:53 AM] [AT] Roll.scanRoll: Eowyn
[6/23/2026 10:33:53 AM] [AT] [AT_Damage.applyDamageDecorator (before apply)] heal


Are you using any other extensions that might be interacting with healing/damge rolls?

Also just in case - have you updated recently? I do recall a bug where the code was checking the type for "heal" (which missed "recovery" healing from short rests), but that was fixed by checking for "not damage":

if rRoll.sType ~= "damage" then return; end -- may be "heal" or "recovery"

This is what the console is giving me for an attempt to use a Potion of Healing and a Cure Wounds.


[6/23/2026 10:58:08 AM] [AT] scanPower Qaspiel: Potion of Healing
[6/23/2026 10:58:12 AM] [AT] Roll.postRoll type: heal; source: Qaspiel
[6/23/2026 10:58:12 AM] [AT] Roll.postRoll [heal]: [HEAL] Potion Of Healing
[6/23/2026 10:58:12 AM] [AT] Roll.dispatchRoll: Qaspiel heal - [HEAL] Potion Of Healing
[6/23/2026 10:58:12 AM] [AT] Roll.annotateRoll: [HEAL] Potion Of Healing; # = 2
[6/23/2026 10:58:12 AM] [AT] Roll.scanRoll: Qaspiel
[6/23/2026 10:58:12 AM] [AT] [AT_Damage.applyDamageDecorator (before apply)] heal
[6/23/2026 10:58:56 AM] [AT] Power.performActionDecorator: nil - nil
[6/23/2026 10:58:56 AM] [AT] Power.checkPower Qaspiel; power: Cure Wounds; school: abjuration
[6/23/2026 10:58:56 AM] [AT] Cast.scanSpell Qaspiel: Cure Wounds (1)
[6/23/2026 10:58:56 AM] [AT] Cast.scanBattleSpells: Qaspiel
[6/23/2026 10:58:58 AM] [AT] Roll.postRoll type: heal; source: Qaspiel
[6/23/2026 10:58:58 AM] [AT] Roll.postRoll [heal]: [HEAL] Cure Wounds [MOD: WIS (1)]
[6/23/2026 10:58:58 AM] [AT] Roll.dispatchRoll: Qaspiel heal - [HEAL] Cure Wounds [MOD: WIS (1)]
[6/23/2026 10:58:58 AM] [AT] Roll.annotateRoll: [HEAL] Cure Wounds [MOD: WIS (1)]; # = 2
[6/23/2026 10:58:58 AM] [AT] Roll.scanRoll: Qaspiel
[6/23/2026 10:58:58 AM] [AT] [AT_Damage.applyDamageDecorator (before apply)] heal




But, still no healing applied to the character that was targeted for Cure Wounds, or dragged and dropped for the Potion of Healing.

I am using the WOB: Life Drain extension - so maybe that's the problem?

EDIT: Just checked with Life Drain not loaded - still no healing applied.

And, to answer the update question - I update at least daily.

jkeller
June 23rd, 2026, 16:51
No luck duplicating the healing bug yet. Anyone else having issues?

What other extensions are you running? I've been testing with just Achievement Tracker mostly.

jkeller
June 23rd, 2026, 17:02
But, still no healing applied to the character that was targeted for Cure Wounds, or dragged and dropped for the Potion of Healing.

Do the healer's stats get updated?

67976

Atreides Ghola
June 23rd, 2026, 17:27
Do the healer's stats get updated?

67976

Yes, the healer's stats get updated.

I have several other extensions running - but only the one (WOB: Life Drain) that I know of that interfaces with healing.

It doesn't post the normal healing message or target information in the chat, either. In the first picture, the heal that shows the GM icon was dragging the heal from the chat to the target.

67980

67981

Atreides Ghola
June 23rd, 2026, 18:07
I just tested with no other extension besides Achievement Tracker 5e, and get the same results - no healing applied.

jkeller
June 23rd, 2026, 18:35
I just tested with no other extension besides Achievement Tracker 5e, and get the same results - no healing applied.

ok, thanks! My next guess is there is some option that we have set differently, and that's affecting it. But I can't think of any that could be related. I'll keep digging.

jkeller
June 23rd, 2026, 20:27
I made some minor changes that *might* help, and added some traces that will provide some additional information.

If you get a chance to try again, please let me know how it goes. If it still fails to heal, the traces from the console.log may give us a clue.

Atreides Ghola
June 23rd, 2026, 21:27
Checked it out again, still no love.

Leaving the house for now - won't be able to check in again until later tonight.