Renormalizing Our Guides


Recent discussions have made me realize that we ought to be thinking of our guides as databases. Back in the 70’s, this nifty new kind of database appeared—called a “Relational Database”—and we programmers thought it was terrific (I was doing CODASYL programming in COBOL at the time: ¡El horror!). There was also this new idea of “Normalization” that popped up. The basic idea was to minimize redundancy.

Let us take the first (faked) set of Worgen quests:

A Lockdown! |QID|14078|Z|GilneasCity|M|59.11,23.83|N|From Prince Liam Greymane right in front of you.|
T Lockdown! |QID|14078|Z|GilneasCity|M|54.65,16.68|N|Go north and then west along the street to Lieutenant Walden lying on the ground.|
A Something's Amiss |QID|14091|Z|GilneasCity|M|54.64,16.68|
T Something's Amiss |QID|14091|Z|GilneasCity|M|59.80,22.23|N|Back to Greymane.|
A All Hell Breaks Loose |QID|14093|Z|GilneasCity|M|59.80,22.23|N|From Prince Liam Greymane.|
A Evacuate the Merchant Square |QID|14098|Z|GilneasCity|M|59.81,22.23|N|From Prince Liam Greymane.|
A Salvage the Supplies |QID|14094|Z|GilneasCity|M|59.58,26.77|N|Go a few steps south to Gwen Armstead.|
C All Hell Breaks Loose |QID|14093|N|Kill Rampaging Worgen.|Z|GilneasCity|M|58.8,32.7|S|
C Salvage the Supplies |QID|14094|N|Look for Supply Crates near the buildings.|Z|GilneasCity|M|58.8,32.7|S|
C Evacuate the Merchant Square |QID|14098|N|Click on Merchant Square Doors.|Z|GilneasCity|M|58.8,32.7|S|
C All Hell Breaks Loose |QID|14093|N|Kill Rampaging Worgen.|US|Z|GilneasCity|
C Salvage the Supplies |QID|14094|N|Look for Supply Crates near the buildings.|US|Z|GilneasCity|
C Evacuate the Merchant Square |QID|14098|N|Click on Merchant Square Doors.|US|Z|GilneasCity|
T Salvage the Supplies |QID|14094|Z|GilneasCity|M|59.59,26.77|N|Back to Gwen Armstead.|
T All Hell Breaks Loose |QID|14093|Z|GilneasCity|M|59.80,22.23|N|Back to Greymane.|
T Evacuate the Merchant Square |QID|14098|Z|GilneasCity|M|59.80,22.22|N|Back to Greymane.|

Now, there is lots of repeated information in each of those lines—and I even introduced some inconsistencies in some locations, just to make a point. Try to spot them! But if we “Normalized” this “table” and threw in some improvements, just for fun, then we end up with four tables:

QID=14091|Accept=34863|Turnin=34913|Title=Something's Amiss|Pre=14078|
QID=14093|Accept=34913|Turnin=34913|Title=All Hell Breaks Loose|Pre=14091|
QID=14098|Accept=34913|Turnin=34913|Title=Evacuate the Merchant Square|Pre=14091|
QID=14094|Accept=34936|Turnin=34936|Title=Salvage the Supplies|Pre=14091|

NPC=34850|Name=Prince Liam Greymane|Map=59.11,23.83|Zone=GilneasCity|
NPC=34863|Name=Lieutenant Walden|Map=54.65,16.68|Zone=GilneasCity|
NPC=34913|Name=Prince Liam Greymane|Map=59.80,22.23|Zone=GilneasCity|
NPC=34936|Name=Gwen Armstead|Map=59.58,26.77|Zone=GilneasCity|
NPC=34884|Name=Rampaging Worgen|Map=55.2,26.5;55.4,26.1;55.4,27.5;55.5,26.7;55.5,27.5|Zone=GilneasCity|

ITEM=46896|Name=Salvaged Supplies|

A Lockdown!|QID|14078|NPC|Prince Liam Greymane|
T Lockdown!|QID|14078|NPC|Lieutenant Walden|
A Something's Amiss|QID|14091|NPC|Lieutenant Walden|
T Something's Amiss|QID|14091|NPC|Prince Liam Greymane|
A All Hell Breaks Loose|QID|14093|NPC|Prince Liam Greymane|
A Evacuate the Merchant Square|QID|14098|NPC|Prince Liam Greymane|
A Salvage the Supplies|QID|14094|NPC|Gwen Armstead|
K All Hell Breaks Loose|QID|14093|T=34884;Kill Rampaging Worgen|QO|1|S|
C Salvage the Supplies|QID|14094|L|46896;4|N|Look for Supply Crates near the buildings.|S|
C Evacuate the Merchant Square|QID|14098|N|Click on Merchant Square Doors.|S|
T Salvage the Supplies|QID|14094|NPC|Gwen Armstead|
T All Hell Breaks Loose|QID|14093|NPC|Prince Liam Greymane|
T Evacuate the Merchant Square|QID|14098|NPC|Prince Liam Greymane|

Now that last table still has redundant information: the NPC tag is irrelevant, as is the step title. The information is in the QID and NPC tables. But these guides are edited by human beings, so they still serve as an aid to us humans.

Factoring the information this way points out some interesting information. First, “Prince Liam Greymane” is really two different NPCs with different locations. Second, by collecting the location information about each NPC into one place, fixing the location means fixing one location in the guide.

So why bother doing this?

  • First off, we win by making all our quest information consistent.
  • Second, any inconsistencies become easier to repair.
  • Third, supporting other languages becomes easier.

So: how hard would it be? Not too bad. The parser could be extended to support the additional QID, NPC and ITEM lines. Each step line in the new form could be filled in from the QID, NPC and ITEM lines, and a synthesized line created and parsed using the current parser. Even most of the N tags could be automatically generated for the A and T steps. That way, each guide could be converted independently. The Python script I use to check the syntax of each guide file could be converted into a “Normalizer” without too much effort. The script could also make an effort to correct coordinates as much as possible.

Later we could consider collecting all the QUEST and the NPC information into their own files, or even consider using a library like Grail, after a thorough cross-check.

There was one guide, which I will not mention by name, that had over 200 bad coordinates in it. Even my spouse—who I can normally talk into editing anything (OCD English Majors have their uses)—gave up trying to edit it, and I’ve been trying to come up with a semi-automatic way of dealing with it ever since. I am sure it is not the only one that could use a normalization makeover.

PS: Yes, this was edited by you-know-who. Note the use of em-dashes, which only an editor would care about. Note the lack of two spaces after a period. Sigh.

  • img
    Jun 9, 2011 @ 6:23 am

    great thanksgreat thanks

  • img
    Jun 8, 2011 @ 22:13 pm

    Wandering NPCYup!  I remeber that quest line.   Depending on how we wanted to structure things, there could be a quest specific location in the NPC record, or a npc location override in the quest record, or a step location override.  Plenty of ways to deal with the many ways that Blizzard implemented the game.Sigh.    

  • img
    Jun 8, 2011 @ 13:17 pm

    The way I handled NPCs thatThe way I handled NPCs that move but have the same Blizzard NPC ID is to have Grail is to create a different NPC ID for them within the Grail database, and the quests refer to that ID as appropriate.  The NPC is also marked with its alias (original) NPC ID so that can be used for any Blizzard API use if needed.  So, for some NPCs (like in Vashj’ir) there are more than three aliases, but as you progress through the quest chain the NPC that is needed can be pointed at by TomTom or whatever successfully because Grail knows the new proper locations because they have been manually created to be correct.

  • img
    Jun 8, 2011 @ 8:48 am

    I did think of an issue withI did think of an issue with this though, and it’s the same issue that caused problems for us in the past when using external automatically generated databases – NPCs move, during phasing mostly. There are NPCs that have the same exact ID (thoguh sometimes they change IDs) but are in compeltely different places on the map depending on the quest you are on. The tiger goddess (can’t recall her name) in the troll city in Northrend is the best example I can think of. She moves during the quest chain but does not change NPC IDs. We would need a way to override coordinates from the database in the quest steps, though we’d need to encourage people to only use it as necessary.

  • img
    Jun 8, 2011 @ 6:37 am

    I very much like this idea,I very much like this idea, I’d like to see this stuff in separate files if possible. Using a library might be nice for this, but introducing more dependencies should be viewed with caution.One of the main things I was hoping to work on when I returned was normalizing the voice and feel of the guides, and it sounds like this could only help that!

Leave a Reply

Your email address will not be published. Required fields are marked *

The reCAPTCHA verification period has expired. Please reload the page.