Trying to understand how emulation works

Im a noob and i was wondering if anyone could explain how trinitycore actually works and how it’s developed. Im assuming it’s begins with reverse engineering using the wow client, how is that done? Also how do you go about updating at each expansion, you must have to just get the maps files etc then what? How do you get the NPC’s in the right place and doing the correct job? I was wondering if you could way mop map on cataclysm private server. Obviously the new classes wouldnt be around but would it be possible or is that actually the first step you do when updating trinitycore to the next expansion?

It’s black magic.

The phrase “If you have to ask, you wouldn’t understand the answer.” likely applies here.

Although I hate to say “it’s really complicated”, it is.

Packet sniffers are used to capture the packets between the retail server & clients. Then people with way too much fucking time on their hands (lol) examine those packets very carefully and figure out what they mean. They then write a server that reads and sends those packets to and from the client. A database is created to allow the emulator to track player activity (position, spells cast, etc) and also the location of every game object and npc picked up by the sniffers.

It has literally taken many years for wow emulators to get to the polished state that TC is in today, thanks to the work of hundreds of programmers donating their free time. It is truly an open-source marvel, but maybe you’d have to be a software developer to really understand what a daunting task this must have been.

Actually sniffs are mosty needed for the database. That’s how people in the private server business take as much data as possible from Blizzard. ( The rest is made up ).

The figuring out part works by reversing the client, using a disassembler. As far as I am aware mostly IDA, as it’s quite convenient, also it can generate fairly understandable C code.

Sometimes Blizzard messes up and releases debug builds, in which case it’s easier to do so.

Updating to a new version is done by bindiffing the binaries, and then checking and implementing the changes.

Prove it.

Maybe once in the histroy of Blizzard patching by mistake, but Blizzard has an entire Quality Assurance department dedicated to rules and standards before releasing to the public. One of thier first 3 rules are to not release in debug… ever!

  • they did it with a mac binairy in 4.1 and few others in MoP’s beta builds.

Then someone is losing thier job. Iv’e stood in the Blizzard’s Irvine department and seen the rule sheet plastered on the wall.

I think they released 2 or 3 builds with debug symbols (one in alpha and two in cata, if I’m not mistaken). I think they were all mac builds.

Interesting, thanks for explaining. I’m assuming most of the code is reused from previous expansions when updating expansions? And it’s edited depending on what is found from the packet sniffing? How long did it take to update from Burning Crusades to Litch King to a stable level roughly? I should be asking on a different forum but as I’m here, do any of you have any suggestions on where I should look to start to try and understand and eventually know enough to help with TC?

Are you trying to update your server to MoP or something?


The more you help, even by tweaking some some effects in the game will get you an understanding of how the client works and the limitations of presenting the models, maps and visability. Technically you don’t need a server until you want to interact with other people. The server passes the origins, the client reads it, same for spells, NPC interaction, etc…

That’s probably the quick and dirty view of how the server works.

All you have to do is a Google search…

Not entirely, sniffs are highly used when figuring out packet structures and usage.

Pretty sure Burlex reversed WOTLK packet structures without any packet sniffs.

Granted there’s been lots of changes since then. So you might need them now.

You might get the packet structure from reversing alone, but in most cases you can end up without the slightest idea of what kind of data goes into each field, that’s why you need sniffs, to give you an idea.

Then you check what happens with that data.

Simply observing what kind of values are sent doesn’t help much.

I remember when I implemented WOTLK refundable items, I knew what type of data the server sent, but had to guess quite a while until I got it right.

Since I have no reversing skills ( I’m just a lowly programmer ) that’s all I could do.

Yeah. I came up with a few mac clients, other ones were just a wild guess on the release only by crashes that dumped…

Trust me, I’ve been searching high and low.

Anyways, not really related to the topic, but I noticed in the several small version patches with the 4.x clients that the wdb caching for the client tables have been rewritten. I’ve parsed some of them, but the table structure looks completely different from mine.

This just doesn’t seem right to me…

Maybe I’m doing something wrong.




<field type="int" name="id"/>

<field type="int" name="quality"/>

<field type="uint" name="flags"/>

<field type="uint" name="flags2"/>

<field type="int" name="buyprice"/>

<field type="int" name="sellprice"/>

<field type="int" name="inventorytype"/>

<field type="int" name="allowableclass"/>

<field type="int" name="allowablerace"/>

<field type="int" name="itemlevel"/>

<field type="int" name="requiredlevel"/>

<field type="int" name="requiredskill"/>

<field type="int" name="requiredskillrank"/>

<field type="int" name="requiredspell"/>

<field type="int" name="requiredhonorrank"/>

<field type="int" name="requiredcityrank"/>

<field type="int" name="requiredreputationfaction"/>

<field type="int" name="requiredreputationrank"/>

<field type="int" name="maxcount"/>

<field type="int" name="stackable"/>

<field type="int" name="containerslots"/>

<field type="int" name="stat_type1"/>

<field type="int" name="stat_type2"/>

<field type="int" name="stat_type3"/>

<field type="int" name="stat_type4"/>

<field type="int" name="stat_type5"/>

<field type="int" name="stat_type6"/>

<field type="int" name="stat_type7"/>

<field type="int" name="stat_type8"/>

<field type="int" name="stat_type9"/>

<field type="int" name="stat_type10"/>

<field type="int" name="stat_value1"/>

<field type="int" name="stat_value2"/>

<field type="int" name="stat_value3"/>

<field type="int" name="stat_value4"/>

<field type="int" name="stat_value5"/>

<field type="int" name="stat_value6"/>

<field type="int" name="stat_value7"/>

<field type="int" name="stat_value8"/>

<field type="int" name="stat_value9"/>

<field type="int" name="stat_value10"/>

<field type="int" name="stat_unk1_1"/>

<field type="int" name="stat_unk1_2"/>

<field type="int" name="stat_unk1_3"/>

<field type="int" name="stat_unk1_4"/>

<field type="int" name="stat_unk1_5"/>

<field type="int" name="stat_unk1_6"/>

<field type="int" name="stat_unk1_7"/>

<field type="int" name="stat_unk1_8"/>

<field type="int" name="stat_unk1_9"/>

<field type="int" name="stat_unk1_10"/>

<field type="int" name="stat_unk2_1"/>

<field type="int" name="stat_unk2_2"/>

<field type="int" name="stat_unk2_3"/>

<field type="int" name="stat_unk2_4"/>

<field type="int" name="stat_unk2_5"/>

<field type="int" name="stat_unk2_6"/>

<field type="int" name="stat_unk2_7"/>

<field type="int" name="stat_unk2_8"/>

<field type="int" name="stat_unk2_9"/>

<field type="int" name="stat_unk2_10"/>

<field type="int" name="scalingstatdistribution"/>

<field type="int" name="damagetype"/>

<field type="int" name="delay"/>

<field type="float" name="rangedmodrange"/>

<field type="int" name="spellid_1"/>

<field type="int" name="spellid_2"/>

<field type="int" name="spellid_3"/>

<field type="int" name="spellid_4"/>

<field type="int" name="spellid_5"/>

<field type="int" name="spelltrigger_1"/>

<field type="int" name="spelltrigger_2"/>

<field type="int" name="spelltrigger_3"/>

<field type="int" name="spelltrigger_4"/>

<field type="int" name="spelltrigger_5"/>

<field type="int" name="spellcharges_1"/>

<field type="int" name="spellcharges_2"/>

<field type="int" name="spellcharges_3"/>

<field type="int" name="spellcharges_4"/>

<field type="int" name="spellcharges_5"/>

<field type="int" name="spellcooldown_1"/>

<field type="int" name="spellcooldown_2"/>

<field type="int" name="spellcooldown_3"/>

<field type="int" name="spellcooldown_4"/>

<field type="int" name="spellcooldown_5"/>

<field type="int" name="spellcategory_1"/>

<field type="int" name="spellcategory_2"/>

<field type="int" name="spellcategory_3"/>

<field type="int" name="spellcategory_4"/>

<field type="int" name="spellcategory_5"/>

<field type="int" name="spellcategorycooldown_1"/>

<field type="int" name="spellcategorycooldown_2"/>

<field type="int" name="spellcategorycooldown_3"/>

<field type="int" name="spellcategorycooldown_4"/>

<field type="int" name="spellcategorycooldown_5"/>

<field type="int" name="bonding"/>

<field type="string" name="name"/>

<field type="string" name="name2"/>

<field type="string" name="name3"/>

<field type="string" name="name4"/>

<field type="string" name="description"/>

<field type="int" name="pagetext"/>

<field type="int" name="languageid"/>

<field type="int" name="pagematerial"/>

<field type="int" name="startquest"/>

<field type="int" name="lockid"/>

<field type="int" name="material"/>

<field type="int" name="sheath"/>

<field type="int" name="randomproperty"/>

<field type="int" name="randomsuffix"/>

<field type="int" name="itemset"/>

<field type="int" name="maxdurability"/>

<field type="int" name="area"/>

<field type="int" name="map"/>

<field type="int" name="bagfamily"/>

<field type="int" name="totemcategory"/>

<field type="int" name="socketcolor_1"/>

<field type="int" name="socketcolor_2"/>

<field type="int" name="socketcolor_3"/>

<field type="int" name="socketcontent_1"/>

<field type="int" name="socketcontent_2"/>

<field type="int" name="socketcontent_3"/>

<field type="int" name="socketbonus"/>

<field type="int" name="gemproperties"/>

<field type="float" name="armordamagemodifier"/>

<field type="int" name="duration"/>

<field type="int" name="itemlimitcategory"/>

<field type="int" name="holidayid"/>

<field type="float" name="statscalingfactor"/>

<field type="int" name="field_130"/>

<field type="int" name="field_131"/>

No im not trying to update to mop :L I can barely say Hello using C++ :L I was just curious.

So do you need the cataclysm server working before moving onto mop. If i had the ability i’d definitely find it tempting just to move up to mop? or is the cataclysm server required?