# Using Cheat Engine to give myself gold in Majesty

I currently aspire to create an AI to play the game [Majesty: The Fantasy Kingdom Sim](https://en.wikipedia.org/wiki/Majesty:_The_Fantasy_Kingdom_Sim).

One important part of building this AI will be allowing it to know what actions it can perform. Almost all meaningful actions in Majesty will consume gold, so knowing how much gold we have in the royal treasury is critical.

I'll be using [Cheat Engine](https://github.com/cheat-engine/cheat-engine) to perform this task.

# Finding the gold value for a single game

First, let's start a game and see that we have `20000` gold. We can use Cheat Engine to pull up all of the memory addresses that store the value `20000`.
![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1658704742576/jwl4bnWMo.png align="left")

Then, we can buy something in the game and have Cheat Engine filter this list to contain only the memory addresses that now have `19600`.
![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1658704797635/DbJJwJUdw.png align="left")

In this case, there is only one address, with the value `0x107E5CB8`. You can double-click it to preserve the address in Cheat Engine.

One big problem though - this address isn't consistent! Every game of Majesty will store its gold value in a different memory address. Instead of performing this manual scan for every game, it would be great to know ahead of time where the gold value for the game will be located.

# Memory offset

You could imagine the gold value for a game being stored in a data structure like this:

```cpp
class Game {
  bool hasEnded;
  bool isMultiplayer;
  uint32_t questId;
  uint32_t timeElapsed;
  uint32_t currentGold; // <--- this is the value we want
  uint32_t workerCount;
}
```

The location where `Game` is stored in memory will change for every game. However, the `currentGold` location _inside of the `Game` structure_ will never change - it was compiled with the game's code!

In the above example, if `bool` has a size of 1 byte, and `uint_32` has a size of 4 bytes, the _offset_ for `currentGold` would be 10 bytes.

Cheat Engine has a method for finding this offset. First, right-click the saved memory address and click "Find out what accesses this address":
![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1658705500244/rbg1TXf0c.png align="left")

Resume the game and make another purchase. Notice the opcode accesses:
![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1658705588621/nUSAySVQE.png align="left")

In this case, that `+10` attached to each operation means we have an offset of 10. This will help us later.

# Pointer scanning and pointer mapping

To find out how to get to your friends' house, you want a set of directions. Start at your apartment, turn left onto 90, turn left onto 405, exit and Main street, look for house number 1184.

Similarly, what we want is a set of directions for how to find gold value of a Majesty game. Start at the base of Majesty's address space, move down 10,000 bytes, follow the pointer at that address, move 50 bytes, follow the pointer at _that_ address, etc.

Creating this set of instructions for a memory address is called _pointer scanning_. We'll try it out now.

Right click on the current gold address and select "Pointer scan for this address"
![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1658706038617/uFqEyNTXl.png align="left")

In the next menu, the only value we need to change is to add the offset we discovered earlier. This tells Cheat Engine "you last step is going to be to move 10 bytes down".
![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1658706253295/ps7Ozw1Hs.png align="left")

In the results, you'll notice two things. One - the number of results is impossibly high! Two - not all of the results make sense. For example, why would a set of directions start with "AquaSnap.dll"?
![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1658706329032/Qu74dxPek.png align="left")

We need to pare down this list. Close that dialog. Right click the memory address, and click "generate pointer map". This will save a list of all of the possible routes to our gold address.

Now, go back to the Majesty main menu, and start a new game. Use the process from before to find the current gold value, and generate a pointer map for it.
![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1658706850121/Oh4-Qct2b.png align="left")

Now, right click on the new gold address and select "Pointer scan for this address". We'll do the same thing as last time, except:
- Check "Use saved pointermap", and input the file from the _current_ game's scan
- Check "Compare results with other saved pointermap(s), input the file from the _old_ game's scan, and make sure to select its address in the dropdown
![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1658706988627/PbErn5fwH.png align="left")

The result should be a bit more favorable. For me, it was only 189 possible paths:
![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1658707024491/y4fCWihfw.png align="left")

It worth noting: multiple of these paths could be valid! Similar to how you can take the back roads to get to your friend's house.

# What's the best way to my friend's house?

Let's double-click a bunch of the values from this pointer scan that start with `"MajestyHD.exe"+...`. 
![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1658707107786/83ccDZ5jg.png align="left")

Now, let's go back to the main menu in Majesty and start _another_ new game.
![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1658707198346/YramFXx8Y.png align="left")

Notice how _some_ of the pointers point to the correct gold value (`8500`) and others don't have the correct path (pointing to garbage memory).

If you continue to start new games and remove the invalid pointers, you will eventually find ones that consistently work. For example:
![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1658707304207/Bqmf7DTZF.png align="left")

We've reached our goal! For any arbitrary instance of Majesty, we're now reasonably confident that we can follow this specific path of pointers to reach out current gold value.

Just to be sure, we can give ourselves an unreasonable amount of money by manipulating the value stored at the memory address.

![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1658707751031/R46rKf-9N.png align="left")

That should be enough for plenty of guardhouses.


