OK, so this is a strange one. It's directly related to #24711, which implemented something resembling the end result of this, but with a hack. I want to show here that there are more cases like this, and maybe somehow come together to an understanding how this is done and whether we need a separate system for this.
TL;DR: Blizzard has some way to show/hide quests on a per-player basis which has no connections to quest chaining or to conditions.
First of, about #24711.
Like stated before, that implementation is a hack. The author modified an unused quest 5209 to serve as the pre-quest of sorts for quest 5382 "Doctor Theolen Krastinov, the Butcher", and made completion of said unused quest be invisible to the player by adding a "tracking" flag to it. But if we were to look at what are the first ever use cases of that flag (Flags&1024) we'd notice that the first quest that uses it has ID of 8152, which is way later into classic development than the quest in question. So either we're missing info about a lot of these quests from classic (unlikely), or that is, in fact, an incorrect way of fixing the issue. The fact that QUEST_EXPANSION_ONLY (added during TBC development) flag goes BEFORE QUEST_FLAGS_TRACKING adds additional credibility to the latter.
If the issue with "Doctor Theolen Krastinov, the Butcher" was the only case of this feature being used - a hack would've been a tolerable solution. But I found at least 2 more cases of it over the past year of playing Classic, one of them even being about 10 meters away from Eva Sarkhoff. :D
This is the one from the aforementioned issue. It's the first one I encountered that had me seriously confuddled about its implementation. Go look at the video linked in the issue, here's a short summary:
My first thought was that the NPC was just getting NPC_FLAG_QUESTGIVER set after going through the gossip, and losing it some time later. But that turned out to not be true, because I could turn the quest in hours and even days after having accepted it without having to gossip with the NPC again. Not to mention how impractical would it be to have to constantly listen to the sob story every time you want to progress the questline.
So then my second thought was: I know that blizzard can change the questlist of an NPC at runtime (AI_GROUP_UNIT_QUESTGIVER takes a reference to a "Quest Giver" record as the parameter), and it is used at the very least with NPC 9836 Mathredis Firestar - when you have a Libram in your bags - he presents you with a gossip option, after clicking which he changes his questlist to one that contains ONLY the quest for that libram, and resets back to the original empty questlist by timeout a few minutes later or after you turn the quest in. So, with that in mind, I thought that Eva Sarkhoff had two questlists - one where she doesn't offer "Doctor Theolen Krastinov, the Butcher", but accepts its turn-in and offers/accepts all subsequent quests from the questline; and one where she offers "Doctor Theolen Krastinov, the Butcher" in addition to everything else, and clicking through the gossip options switches her questlist from the first to the second, allowing you to take "Doctor Theolen Krastinov, the Butcher", but still allowing you to turn it in as well as pick up and turn in all the subsequent quests even if her questlist resets back. Sadly, I was pressed for time back then, and couldn't fully test this theory, so I just accepted the quest and completed the questline. And so I remained, thinking that I cracked blizzard's script, until I encountered...
This quest's questgiver is scripted in the exact same way: you can't see the quest initially, you click through options, and then you can pick up the quest. But this time I was prepared! I waited. 5 minutes. 10. 30. An hour passed, but he wouldn't stop offering me the quest. I quit the game, and came back the next evening but the blasted Magistrate was STILL offering me the quest. So I asked a guildie (who, luckily, hadn't discovered this quest yet) to tell me what he sees. And he couldn't see the quest! While I could, standing right beside him. Not until he also clicked through the options. This completely destroyed any theory of NPC toggling his NPC_FLAG_QUESTGIVER or changing his questlist, because now it was personal! I mean, if it was the NPC changing, other players would experience the same changes (like with the Mathredis Firestar I mentioned above - I verified it with another player, they could also see the quest when he was changing his questlist), but in this case the change was specific to each one of us.
Video of the gossip: https://i.imgur.com/fbJ0OUp.mp4 (sorry about the pauses, I was reading the text, I sped it up 4x)
Can also provide the video of me walking my guildie through the motions and getting his responses about what he was seeing.
This was actually the very first quest I encountered to be using this feature, but I didn't know it at the time. It's implemented the same way: you click through the gossip options -> you start seeing the quest. But you can't see the gossip option until you... visit Dire Maul area. Worse even, there are no areatriggers for this! According to the wowhead comments (both from vanilla and from classic) the gossip option only becomes visible after you simply visit the Dire Maul area once, you don't even need to enter the actual instance (in which case we could've made an argument that the teleporting areatrigger causes it). Luckily, it seems like PlayerCondition::Explored is responsible for checking this. The gossip option must have had a PlayerCondition attached to it that would check if the player has Dire Maul area explored.
None of these 3 quests have any pre-quests.
This means that blizzard has one more way to make a quest available or unavailable to the player. One that doesn't involve chaining quests together and requiring the player to complete the previous quests before they can complete the next one.
I don't know. Not the answer you expected, and, likewise, not the answer I wish to give. But I simply don't know. It's not something I ever knew about until yesterday.
I examined all the possible places I could think of that could limit the quest's availibility:
QUEST_FLAG_TRACKING in classic anywhere near the ID range of the 3 quests I mentioned.If you can think of any other place that I missed - let me know, I'm dying to know.
But for now, we have to assume that it's a straight up feature that we didn't know about until now. And that we, of course, don't have implemented.
I dug through the Alpha client I have in search for something even tangentially related to this feature, and I did find... something...
There are these console commands present in the Alpha client:
| Command | Parameters | Function it calls | Opcode it sends |
| --- | --- | --- | --- |
| clearquest | quest(id) | CCommand_ClearQuest | CMSG_CLEAR_QUEST |
| flagquest | quest(id) | CCommand_FlagQuest | CMSG_FLAG_QUEST |
| finishquest | quest(id) | CCommand_FlagQuestFinish | CMSG_FLAG_QUEST_FINISH |
| questquery | questGiver(guid) quest(id) | CCommand_QuestCommand > QueryQuest | CMSG_QUESTGIVER_QUERY_QUEST |
| questaccept | questGiver(guid) quest(id) | CCommand_QuestCommand > AcceptQuest | CMSG_QUESTGIVER_ACCEPT_QUEST |
| questcomplete | questGiver(guid) quest(id) | CCommand_QuestCommand > CompleteQuest | CMSG_QUESTGIVER_COMPLETE_QUEST |
| questcancel | questGiver(guid) quest(id) | CCommand_QuestCommand > QuestLogRemoveQuest | CMSG_QUESTLOG_REMOVE_QUEST |
As you can see, the last 4 just mimic normal client activity (simulating the process of talking to a questgiver or deleting a quest from the questlog), but the first 3 ones are dev cheats, opcodes that aren't used by regular players during regular gameplay, akin to godmode, beastmaster mode, debug, etc. clearquest is pretty straightforward, it should be the same as our .quest remove - deletes the record that the player had completed the quest. But the two other ones are curious. For some reason quests can be either "flagged" or "flagged as finished". If "flagged as finished" would mean adding a record that the player has completed and rewarded the quest, then what does it mean for a quest to simply be "flagged"? Perhaps that the player is eligible to start that quest, if it's disabled by default? Recall that quest status enum has two additional seemingly unused values: QUEST_STATUS_UNAVAILABLE and QUEST_STATUS_AVAILABLE. Could this be related?
In any case...
I don't know where is it defined that a quest must be unavailable by default. There are no flags related to that. Perhaps it's a serverside field that they didn't bother including in DBC/cache?
I don't know how blizzard is making quests available from scripts. There are no AI Group Actions in any Wow.exe (I checked alpha/vanilla/wotlk/legion) that could "flag" a quest, or, in fact, do anything other than add/remove/complete/fail it. I am not aware of any other scripting systems they might be employing beyond AI Group Actions and WorldState Actions. There are no spell effects for it either.
Whatever it is, it must be so obscure that almost nobody at blizzard even knows about it, seeing how feature is so scarcely used, that we're only learning about it in 2020, despite it being used all the way back in 2004...
I've seen this behaviour in cataclysm as well, but i think those are just marker quests that cannot be transmitted to the client and they control it that way. As far as the exploration one goes, seems like condition only
I, too, don't think TC lacks quest data since those can be bruteforced but on other hand there are gaps in the quest_template, maybe those are marker quests that are never sent to the client and cannot be queried? We know for a fact that blizzard uses marker quests (ie. argent crusade, maybe they forgot to mark those as non-transmittable) and blizzard isnt really known for being consistent in how they do stuff (yey designers!)
edit:
5500-5600 IDs https://pastebin.com/FKFyqWRJ (thanks @jinnaix)
edit2: My guess regarding CMSG_FLAG_x opcodes is that it's used by internal testers to mark quests that are having issues or not working properly? Those packets, for 3.3.5, are next to other debug opcodes or just GM commands for completing quest for players
@Riztazz, could you perhaps recall what those quests from cataclysm were?
but on other hand there are gaps in the quest_template
These gaps are there mostly for the same reason there are gaps in many other DBCs - for whatever reason blizzard were generating IDs in increments of 20. 1, 21, 41, 61, 81, etc. If you look at the quest title dump you provided - you'll notice that pattern, and it's the same with many other databases: LiquidType (21, 41, 61, 81, 100, 121, 141, 181), Faction (128, 148, 168, 169, 189, 209, 229, 249, ...), AreaTable (2017, 2037, 2057, 2077, ...) and so on. It's as if designers were getting whole chunks of 20 IDs reserved for them whenever they started creating something, to avoid collisions or god knows why.
edit2: My guess regarding CMSG_FLAG_x opcodes is that it's used by internal testers to mark quests that are having issues or not working properly? Those packets, for 3.3.5, are next to other debug opcodes or just GM commands for completing quest for players
Nah, this is definitely wrong. "Flagging" definitely refers to at least marking quests as completed by the player, the name of API function https://wow.gamepedia.com/API_C_QuestLog.IsQuestFlaggedCompleted speaks to that. It's just a question of why there are 2 different ways to "flag" a quest.
I stand corrected. I'll see if i can find that quest later, but i'm pretty sure it was somewhere hyjal
28347 - Coffer of Promise TRACKING QUEST
This one was most likely used to trigger the terrain swap during camera cutscene for the Uldum quest "Coffer of Promise". Not sure if that's what you're after but hope it helps.
Edit: Another few "tracking" quests are used for Archmage Xylem's trials in Azshara:
28886 - Frost Instructions Tracking Quest
28887 - Fire Instructions Tracking Quest
28888 - Shadow Instructions Tracking Quest
28889 - Arcane Instructions Tracking Quest
These ones are used to make sure the player does not receive the texts explaining how Trials work more than once (I presume).
There's also a few tracking quests for the Goblin starting zone, such as "Kill Chip Endale Tracking Quest", "Kill Candy Cane Tracking Quest" or "It's a Town-In-A-Box Tracking Event".
The feature I'm describing has no relation to tracking quests. Tracking quests are a solved problem. The subject of this issue is a feature that existed before tracking flag was even invented. I totally expect that 99% (if not 100%) of all similar occurences in TBC and onwards is implemented via tracking quests, but it wasn't the case for vanilla.
This could just be some dummy server side aura or something similar ie gets cast on gossip yang quest is given if that aura present?
We have all serverside spells from classic, because during classic they weren't hidden from the DBC yet. There are none.
There is a flag that hides a quest until "discovered". No idea if it's been here since classic. I don't remember the value off the top of my head. They also have a "quest has a condition" flag, which might be linked. Didn't investigate, might try to tomorrow since I've been looking at quest flags(odd coincidence) this weekend
Something else worth looking into : WorldStateExpression
We know about it since magic and it started to get shipped in Legion but recent Classic builds seem to have it
@Killyana in the meantime please go change WDBVerified for that quest if you haven't already and slap yourself for touching WDB data
There is a flag that hides a quest until "discovered".
It's a way too recent addition: QUEST_FLAGS_HIDE_UNTIL_DISCOVERED = 0x4000000.
Classic, at that stage of development, didn't have even QUEST_FLAGS_TRACKING = 0x400.
Besides, I'm getting very mixed messages about that QUEST_FLAGS_HIDE_UNTIL_DISCOVERED flag. In Wow.exe this flag is named Quest is Well Known, which kinda goes contrary to the enum name which, I presume, was given by private server devs. But maybe I don't know something about the recent expansions.
They also have a "quest has a condition" flag, which might be linked.
Now that is true. It's a very early flag, 0x10. Its name from the exe - * QUEST_HASCONDITION - never used in WOWEdit. Considering that another flag - * QUEST_COMPLETION_AREA_TRIGGER - automatically set - has a different description from QUEST_HASCONDITION, I can make a guess that QUEST_COMPLETION_AREA_TRIGGER is automatically set when an areatrigger objective is added inside WOWEdit (there are maaaany flags that are automatically toggled when the designer clicks various checkboxes and comboboxes throughout the quest editor windows), but QUEST_HASCONDITION is not set by WOWEdit at all, and is set by the server during runtime, kinda like ours QUEST_SPECIAL_FLAGS_DF_QUEST. But I cannot say for certain, of course, maybe there is a connection. The problem is just that there is not a single quest in our DB that has QUEST_HASCONDITION set.
Something else worth looking into : WorldStateExpression
Maybe. But WorldState would be something that concerns the entire instance/zone/map/world, not one specific player, so I dunno how to tie it into this. There is also this scripting system that reacts to WorldState changes, but there are no mentions of quests in it whatsoever.
unless sure ive came to this conclusion before but was reverse ie on retail npc showing gossip item when only have quest or where should be no gossip until after a quest is rewarded but I wonder how likely it could be for players to see same npc with different npc flags and emotes etc only sent to a single client
retail npc showing gossip item when only have quest or where should be no gossip until after a quest is rewarded
That's obvious, done via PlayerCondition on retail, `conditions` on TC.
but I wonder how likely it could be for players to see same npc with different npc flags
Npc flags are the same for everyone, period. The only fields that can be different per-player are those that are marked as "dynamic" (dynamic flags, and a very few more), that's exactly the purpose of that "dynamic" attribute. We have our own hacks, like changing displayid for GMs etc, but that's another matter entirely, retail doesn't work like that.
and emotes etc only sent to a single client
Emotes (one-shot, not emotestates) can definitely be sent to specific players, because since WotLK they have the ability to send chat and emotes that are visible only to one player:
Unit(s) says something only to a player
Unit(s) yells something only to a player
Unit(s) says something random only to a player
Unit(s) yells something random only to a player
Unit(s) chat emote something to a player
Unit(s) chat emote something random to a player
Unit(s) perform an emote to a player
An example of that are Linda Ann Kastinglow and Arcanist Alec who stand at the entrance to Dalaran from the landing pad and "personally" talk (through monster say, not through monster whisper!) to players who pass through the areatrigger next to them.
Heh, interesting https://youtu.be/cLiXqxd7HZU?t=118
Indeed, seems like a perfect place for another use case of this tech. I haven't done that quest yet on Classic, I'll see if I can get it done until the end of the week, while DMF is still there, and will ask another player to verify that they cannot see the quest at the same time as I'm able to see it, because if they can as well, then it's just a simple case of guestgiver flag being set.
This one too https://www.youtube.com/watch?v=vve0aB4uAq8
At 4:10, for future readers.
So I checked Jubjub. It's NOT using this system. Morja simply becomes a questgiver temporarily after Jubjub approaches her, anyone can get the quest regardless of whether they used the mug or not. After about 2 minutes Jubjub respawns, Morja says "Jubjub? Where are you, Jubjub? Oh no! Where did you go this time!" and stops being a questgiver.
More info about the event
If anyone cares, here's a full description of how it works as I understand it: after dropping a mug, Jubjub starts walking to the mug at first, but once it gets close to Morja, she says her "Hi Jubjub. I missed you!" text and Jubjub starts walking towards her instead. A few seconds later it despawns. 2 minutes later it respawns and starts executing its script, which in Elwynn is basically:
If you throw the mug far away from Morja, then Jubjub simply approaches the mug (uninterrupted by Morja, since it never comes close to her), emotes "%s guzzles down the ale!", despawns the mug, and returns back to where it was and resumes its script.
Quite possible we have sniff of that thing