Register for your free account! | Forgot your password?

Go Back   elitepvpers > Coders Den > General Coding > Coding Tutorials
You last visited: Today at 19:36

  • Please register to post and access all features, it's quick, easy and FREE!

Advertisement



Writing an Hearthstone Combo Helper [No Injection] [Tutorial]

Discussion on Writing an Hearthstone Combo Helper [No Injection] [Tutorial] within the Coding Tutorials forum part of the General Coding category.

Reply
 
Old   #1
 
elite*gold: 0
Join Date: Aug 2013
Posts: 10
Received Thanks: 9
Writing an Hearthstone Combo Helper [No Injection] [Tutorial]

In this tutorial I will show you the full process from "hacking" to actually writing an Combo Helper for Hearthstone.
This is labeled as an tutorial but it also describes some of process I went through to get to the result I got.
The reasoning behind that is to highlight what is the most important trait of anything an programmer do.
How we reason and come up with a working solution. Because that is the truly hard thing and is not taucht in school.
I am assuming you know some programming and HTTP knowledge. Other than that it will be math for the actual statistics but
I leave it optional to actually try to understand it on a deep level.
There is also GUI in ComboHelper but there are so many C# tutorials on GUI so I will leave that to yourself.

First things first
For writing this thing I used C# empowered with BotKitty.
BotKitty is an handful of tools, runtime, API and GUI interface geared towards botwriters. The botwriters can then write plugins for which other users then easily can pick up and start using.

BotKitty can be downloaded here and for those who want read the code and mess with it can download ComboHelper on Github.

Also Cheat Engine is used to do inspect Hearthstone memory.

The goals and requirements
Is to be able to view the chance of getting certain combos of cards as the game is played.
Also to make this an long lasting application no injection or game file modification is allowed.
It should last along patches.

This gives us the following list of requirements for our helper:
- Find out when game starts
- Allow users to modify combos
- Do mathematically exact statistical analysis
- Know about which cards are in the deck as the game is played

The cards
As you might know cards is used in Hearthstone. It is after all a card game and therefore what we need to do is find out which cards has been played and not.
This will require that we inspect the memory of Hearthstone as it is running. But what is the first rule when inspecting another process?
Check how the game is built, if it is Unity or Unreal Engine or if they are using their own custom engine. Is it using C++ only or is there a scripting language to?
All this characterize how memory will be managed and later on this is going to affect what we need to get the cards in a trustful manner.
But let's ignore that for now, I am going to explain that completly. Let's focus on the memory, and for inspecting it we will be using Cheat Engine.

So we want to know which cards is dead, ours and which is not used.
I fired up Hearthstone, entered a match and searched the memory for a card name which I have in hand.
What comes up is very different depending on what cards you search for.
It can be 50 results, or 3. But after going through the surrounding memory of one of them we find something like this:



This is very peculiar, why would any game ever store game state as strings, it is simply very inefficient in almost every way.
Unless it might be cashe for what is sent towards the server. That is my best guess atleast.
Anyway moving forward, we try to play this card which we just searched for and then we search for the game id of our card.
Because that sounds alot like a real id.
And what happens now is that there have been another allocation of an almost identical string, but it's zone value is now "PLAY".
Hmm, we surely got something going here. After more research including searches for zone= this is the list of values we have found out:

zone can have the following values: HAND, PLAY, DECK, GRAVEYARD.
gameId is the unique id of the card throughout the match. (But I do not think that was any surprise.)
cardId is unique id across all cards.
zonePos tells us the position of the card from left to right, except when position == 0 (I'm coming to that)

We certainly need unique identifiers for every card in the game to allow the user to actually add their own cards to their combos.
And this cardId value of the findings in memory really seems to please that constraint.
But with only this information the user will have to add cardId for every card in their deck. That will be fairly enoying to say the least.
So if we could display the cards when the user searches for them that would give users a more interactive and natural course of setting combos.

This is the first time we will see how it becomes important that we know how Hearthstone is built.
And the first step to figure that out is to take a look at the files in the Hearthstone directory.
Or more specificly the Data/Win directory, it contains a bunch of files with the extension .unity3d.
A quick google search tells us that Unity is a game engine which you might have already heard of.
And by taking a look at asset system of the game engine we now know that we can decompile these unity3d files and get animations and images of every card.
Ok, now we know what we need to. But this could potentially be ALOT of work, so let's find out if anyone else have done this before.
Googling for "hearthstone cards by id" gives as first result which contains a link to an machape API.
So turns out we can basicly just "call" this REST api.

Ok, now when we have figured out that this memory search is everything we need it is time to actually do a search.
For this BotKitty offers the MemFind method.
So we just do the search like this:



This is enough to get all cards and also alot more. So we need to go through each of these matches and see if it actually contains all information we need.
If you really want to know how that is done the code is here(it is not pretty):



Unity is using C# as their language for managing the game logic. What this means is that these strings are allocated using the garbage collected heap.
Meaning strings will be along for longer than the actual game logic knows about.
This means that we will see a single card in multiple states by simply inspecting the memory of Hearthstone. We also need some filtering and heuristics
to figure out which cards are representing the card in the current state.

For this we apply a bunch of filters. We say hand cards is only going from right to left or from the zone position perspective from high numbers to lower.
That way we know where it exists in hand, we assume cards is going from deck -> hand -> play -> graveyard. This means if we find a card with it's zone
set to hand and also to deck we know the card is in hand. Of course this is not perfect, but it works good enough.

The zone information in the memory findings is great, but it has one big flaw. How the f** do we know if that card is ours or the enemy players?
Well, as a general rule. When you got data which is just valid for the moment and it is not complete, just build an history list and infer each cards
"alliance" by how the card has went through the zones and from unknown.
I will spare you the details about this because it is alot of huffing and puffing. But what I choose to do is to have two zone states, the current and the last.
Using that I can then build an twodimensional finite state machine. For those who does not know what that is I can explain this "academic" thing with one word,
a grid. Take the current state and the last state and for every combination of these two spit out the alliance.

Take this grid for example:



This is the actual state machine which is used in ComboHelper.
How this is used is you take the x axis(second dimension) and the y axis(first dimension) and then represent that combination with an function which spits out an Alliance value.
The Alliance value can be either friendly, enemy, nochange or invalid.

Now when we got all data we need it is time to actually write an algorithm which calculates the statistics.
So let's start by stating the the different input we are dealing with:
- Round count
- Combo count
- Combo giving cards
- Deck count

Calculate the stats when round count is equal to combo count is the easiest case, so let's begin there.
There is one important twist already there, if you have studied statistics the slightest you know there
is a terminology about statistical outcome area. But the area will change each time to draw a card.
How this is dealt with is that you calculate the permutations of the combo count and deck count.
Eg:
Round Count - 3
Combo Count - 5*4*3=60
Deck Count - 30*29*28=28360

Then they are divided by each other:

Combo Permutations / Deck Permutations

The problem with this method is that how do we deal with when the round count is higher than the combo count.
We need to insert failed draws. But the problem is that they will give different statistics depending on where they are inserted.
After some searching for a method for expressing the average of this change in statistics we find an stack overflow answer telling
us hypergeometric distribution.
I will just give out the answer to how to implement this, as it requires time (for me) to think through.



This tutorial is fairly dense, I must agree with that. And in some areas it is very shallow, there is alot to talk about here.
But I wanted to keep this one short, and if you are interested in a specific topic I suggest you to contact me or to simply read
about that topic.

Hope you got something out of this, bye
Kickupx is offline  
Thanks
2 Users
Old 03/30/2017, 13:38   #2
dotCom
 
Devsome's Avatar
 
elite*gold: 9842
The Black Market: 107/0/0
Join Date: Mar 2009
Posts: 16,866
Received Thanks: 4,685
Quote:
Originally Posted by Kickupx View Post
In this tutorial I will show you the full process from "hacking" to actually writing an Combo Helper for Hearthstone.
This is labeled as an tutorial but it also describes some of process I went through to get to the result I got.
The reasoning behind that is to highlight what is the most important trait of anything an programmer do.
How we reason and come up with a working solution. Because that is the truly hard thing and is not taucht in school.
I am assuming you know some programming and HTTP knowledge. Other than that it will be math for the actual statistics but
I leave it optional to actually try to understand it on a deep level.
There is also GUI in ComboHelper but there are so many C# tutorials on GUI so I will leave that to yourself.

First things first
For writing this thing I used C# empowered with BotKitty.
BotKitty is an handful of tools, runtime, API and GUI interface geared towards botwriters. The botwriters can then write plugins for which other users then easily can pick up and start using.

BotKitty can be downloaded here and for those who want read the code and mess with it can download ComboHelper on Github.

Also Cheat Engine is used to do inspect Hearthstone memory.

The goals and requirements
Is to be able to view the chance of getting certain combos of cards as the game is played.
Also to make this an long lasting application no injection or game file modification is allowed.
It should last along patches.

This gives us the following list of requirements for our helper:
- Find out when game starts
- Allow users to modify combos
- Do mathematically exact statistical analysis
- Know about which cards are in the deck as the game is played

The cards
As you might know cards is used in Hearthstone. It is after all a card game and therefore what we need to do is find out which cards has been played and not.
This will require that we inspect the memory of Hearthstone as it is running. But what is the first rule when inspecting another process?
Check how the game is built, if it is Unity or Unreal Engine or if they are using their own custom engine. Is it using C++ only or is there a scripting language to?
All this characterize how memory will be managed and later on this is going to affect what we need to get the cards in a trustful manner.
But let's ignore that for now, I am going to explain that completly. Let's focus on the memory, and for inspecting it we will be using Cheat Engine.

So we want to know which cards is dead, ours and which is not used.
I fired up Hearthstone, entered a match and searched the memory for a card name which I have in hand.
What comes up is very different depending on what cards you search for.
It can be 50 results, or 3. But after going through the surrounding memory of one of them we find something like this:



This is very peculiar, why would any game ever store game state as strings, it is simply very inefficient in almost every way.
Unless it might be cashe for what is sent towards the server. That is my best guess atleast.
Anyway moving forward, we try to play this card which we just searched for and then we search for the game id of our card.
Because that sounds alot like a real id.
And what happens now is that there have been another allocation of an almost identical string, but it's zone value is now "PLAY".
Hmm, we surely got something going here. After more research including searches for zone= this is the list of values we have found out:

zone can have the following values: HAND, PLAY, DECK, GRAVEYARD.
gameId is the unique id of the card throughout the match. (But I do not think that was any surprise.)
cardId is unique id across all cards.
zonePos tells us the position of the card from left to right, except when position == 0 (I'm coming to that)

We certainly need unique identifiers for every card in the game to allow the user to actually add their own cards to their combos.
And this cardId value of the findings in memory really seems to please that constraint.
But with only this information the user will have to add cardId for every card in their deck. That will be fairly enoying to say the least.
So if we could display the cards when the user searches for them that would give users a more interactive and natural course of setting combos.

This is the first time we will see how it becomes important that we know how Hearthstone is built.
And the first step to figure that out is to take a look at the files in the Hearthstone directory.
Or more specificly the Data/Win directory, it contains a bunch of files with the extension .unity3d.
A quick google search tells us that Unity is a game engine which you might have already heard of.
And by taking a look at asset system of the game engine we now know that we can decompile these unity3d files and get animations and images of every card.
Ok, now we know what we need to. But this could potentially be ALOT of work, so let's find out if anyone else have done this before.
Googling for "hearthstone cards by id" gives as first result which contains a link to an machape API.
So turns out we can basicly just "call" this REST api.

Ok, now when we have figured out that this memory search is everything we need it is time to actually do a search.
For this BotKitty offers the MemFind method.
So we just do the search like this:



This is enough to get all cards and also alot more. So we need to go through each of these matches and see if it actually contains all information we need.
If you really want to know how that is done the code is here(it is not pretty):



Unity is using C# as their language for managing the game logic. What this means is that these strings are allocated using the garbage collected heap.
Meaning strings will be along for longer than the actual game logic knows about.
This means that we will see a single card in multiple states by simply inspecting the memory of Hearthstone. We also need some filtering and heuristics
to figure out which cards are representing the card in the current state.

For this we apply a bunch of filters. We say hand cards is only going from right to left or from the zone position perspective from high numbers to lower.
That way we know where it exists in hand, we assume cards is going from deck -> hand -> play -> graveyard. This means if we find a card with it's zone
set to hand and also to deck we know the card is in hand. Of course this is not perfect, but it works good enough.

The zone information in the memory findings is great, but it has one big flaw. How the f** do we know if that card is ours or the enemy players?
Well, as a general rule. When you got data which is just valid for the moment and it is not complete, just build an history list and infer each cards
"alliance" by how the card has went through the zones and from unknown.
I will spare you the details about this because it is alot of huffing and puffing. But what I choose to do is to have two zone states, the current and the last.
Using that I can then build an twodimensional finite state machine. For those who does not know what that is I can explain this "academic" thing with one word,
a grid. Take the current state and the last state and for every combination of these two spit out the alliance.

Take this grid for example:



This is the actual state machine which is used in ComboHelper.
How this is used is you take the x axis(second dimension) and the y axis(first dimension) and then represent that combination with an function which spits out an Alliance value.
The Alliance value can be either friendly, enemy, nochange or invalid.

Now when we got all data we need it is time to actually write an algorithm which calculates the statistics.
So let's start by stating the the different input we are dealing with:
- Round count
- Combo count
- Combo giving cards
- Deck count

Calculate the stats when round count is equal to combo count is the easiest case, so let's begin there.
There is one important twist already there, if you have studied statistics the slightest you know there
is a terminology about statistical outcome area. But the area will change each time to draw a card.
How this is dealt with is that you calculate the permutations of the combo count and deck count.
Eg:
Round Count - 3
Combo Count - 5*4*3=60
Deck Count - 30*29*28=28360

Then they are divided by each other:

Combo Permutations / Deck Permutations

The problem with this method is that how do we deal with when the round count is higher than the combo count.
We need to insert failed draws. But the problem is that they will give different statistics depending on where they are inserted.
After some searching for a method for expressing the average of this change in statistics we find an stack overflow answer telling
us hypergeometric distribution.
I will just give out the answer to how to implement this, as it requires time (for me) to think through.



This tutorial is fairly dense, I must agree with that. And in some areas it is very shallow, there is alot to talk about here.
But I wanted to keep this one short, and if you are interested in a specific topic I suggest you to contact me or to simply read
about that topic.

Hope you got something out of this, bye
quoted for the pics + moved to tutorial section
Devsome is offline  
Reply

Tags
combo helper, hearthstone, tutorial


Similar Threads Similar Threads
Combo Helper [No Injection]
04/07/2017 - Hearthstone - 1 Replies
HS Combo Helper View statistics about in how many turn you will be able to make your combos. This is done by inspecting the memory of Hearthstone and actually reading text from the window but it is NEVER inserting/injecting/hooking anything. Therefore dodging most of the problems with warden. For pictures on how it looks check it out on Github.
Code/Dll Injection Tutorial
12/13/2014 - Tutorials - 28 Replies
Einleitung Hallo Elite PvPer! http://www.animiertegifs.de/smilies/eckige-Smileys /eckige-smileys-animiert-02.gif Auf folgende Fragen wirst du in diesem Tutorial Antworten finden: Was ist eine "Code/Dll injection" und was bringt mir das - kann man das essen? http://www.greensmilies.com/smile/smiley_emoticons _freddus_msn_fressen.gif Was sind Dll-Dateien (dynamische/statische Bibliotheken) - kann man die ebenfalls essen? http://www.greensmilies.com/smile/smiley_emoticons _essen.gif Wie...
Yet another Quest Writing Tutorial
07/13/2013 - Metin2 PServer Guides & Strategies - 49 Replies
Yet another Quest Writing Tutorial Hello elitepvpers, Today proudly present you my new Quest Writing tutorial. In this tutorial I show you how you can write quests, but I show it to you in my way this means, I show you how to write good quest code, and tell you what you can do and what you can’t. To follow this tutorial you need no special knowledge, but some basics wouldn’t be bad. Let me tell you a little story about what we will do in this tutorial.
Clear Combo Hack tutorial ph
09/18/2009 - Cabal Online - 3 Replies
i just wanted a clear tutorial for combo hack can someone please help me? i really wanted to learn this one, its very helpful for my wizard~ im eager to learn, and i can be a good student~ i hope somebody or someone can help me!!
OMG SQL INJECTION TUTORIAL
11/12/2008 - RF Online - 3 Replies
... k now that i got all of ur undivided attention~~ this for all u dam leechersand about everyone talking about sql injection... from knowing multiple people that can sql inject, tell me do u even know what it stands for or how to do it...



All times are GMT +1. The time now is 19:37.


Powered by vBulletin®
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
SEO by vBSEO ©2011, Crawlability, Inc.
This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

Support | Contact Us | FAQ | Advertising | Privacy Policy | Terms of Service | Abuse
Copyright ©2026 elitepvpers All Rights Reserved.