Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.Sign up
Memory Inspector Overview
Here is an overview of the Memory Inspector and its features. This tool can be found on "RetroAchievements" tab on any emulator integrated with RA.
See also: Memory Digging Tips.
Memory Inspector Dialog
1. Reset to
Click on one of these buttons to start a new test. For most things 8-bit test would be appropriate.
2. Filter Values
Usually filter for either
= (equals to) last known value or
!= (different than) last known value. If you know the exact value you expect something to be, you can use
Given Value, or if you're convinced that a value should have increased, you could try
> (greater than) or
< (less than).
With every press of this button, you are filtering out values that do not match in memory between the last test and now.
4. Results window
After filtering you'll see in the results window exactly what happened, how many values you've got and how many are left. Some points to note:
- Search results show live value changes, so you can more easily identify usable addresses.
- Search results are highlighted depending on their criteria. For addresses that don't fit the search filter, they will be highlighted in red. This can be disabled on the
Highlightscheckbox, if preferred.
- You can also manually exclude any selected addresses from the search. Use Ctrl or Shift to multi-select.
Results History: You can move backwards (
<<) or forwards (
>>) through your previous filtered searches. Keep in mind if you start a new search (such as
New 8-bit Test), your history will be cleared.
Any properly formed value in this area will be watched in the Memory Viewer and bound to the code notes on the right. You can highlight and then arrow up and down here to quickly cycle through noted addresses. The addresses must be
0x (that's zero, then letter x), followed by hexadecimal digits.
6. Memory Viewer
Any watched variable and the variables around it will be shown in this window. You can manually arrow up and down in the viewer to advance the address pane or expand the viewer field by dragging the window vertically to view more addresses at once. Additional info can be found below, in the Reading data in the Memory Viewer section.
7. Code Notes
Once you've found a memory address you want to make a note of, ensure the value is entered into the 'Watching' dropdown box. Next you can write a short description in the textbox next to it, and click
Save Note. This will send the memory address and your description to the database, so it can be shared with all developers who work on this game.
Click the dropdown arrow to view what memory addresses have been found so far, and you will be shown the description in the box next to it, to tell you what this memory address is for.
Try and keep your descriptions simple and clear, so they can be easily understood. To rename a note, select it in the drop-down menu, update the description, and click
Save Note. A dialog will prompt you to overwrite the existing note - check that it is a good change, and click OK.
If you wish to remove a note, select it in the dropdown menu, and click
8. Memory Bookmarks
When you click on the
Open Memory Bookmarker button you'll see this dialog:
With this, you can view multiple designated addresses at once instead of having to shuffle around in the Inspector.
The bookmarks can be renamed by double-clicking their description. If you double-click on the address, you can move straight to that point in the Mem Inspector.
Bookmarked addresses will show in the Memory Inspector as green. From here you can also Freeze any bookmarks.
This is helpful for things like health or consumables. Frozen values can be manipulated directly from the inspector. Keep in mind, freezing occurs 1 frame after gameplay. This means even when frozen, the value will change for atleast one frame before returning to the frozen value. These will always be displayed as yellow.
Reading data in the Memory Viewer
Decimal, Binary and Hexadecimal notations
To work well with the Memory Viewer, it's important to understand at least the basics of binary and hexadecimal numeral notations. Here are good sources of information about this matter without going into extreme details:
The digits used in binary system are
1. A binary digit is also known as bit. Eight bits is also known as one byte.
The digits used in hexadecimal system are
F. The hexadecimal notation is also known as hex.
The main reasons for the existence of these 2 notations, besides the traditional decimal notation, are:
- Decimal notation is what humans understand.
- Binary notation is what computers "understand".
- Hexadecimal notation can be seen as a middle ground between binary and decimal. Because a single hexadecimal digit represents 4 bits, then a shorter and more understandable notation for humans to work in a way that the computer "understands".
The table below shows the different notations for equivalent values.
More facts about the different number notations:
- To indicate a value is written in hexadecimal, the prefix
0x10 = 16,
10 = 10.
- Two hex digits represent 8 bits and can range from
- Four hex digits represent 16 bits and can range
- Eight hex digits represent 32 bits and can range from
Memory Viewer modes
The bottom part of the Memory Inspector is what we call the Memory Viewer:
You can see data in Memory Viewer using 8, 16 or 32-bit modes.
By default, the Memory Viewer shows data in 8-bit mode. This displays each byte of memory as a separate two-character hexadecimal value. And each byte has its own address.
Sixteen bytes are shown per line. The address of a byte can be determined by adding the row index (displayed to the left of the viewer) to the column index (displayed above the viewer). Using the image above as an example, the cursor is at
Before we talk about 16-bit mode and 32-bit mode, it's important to know about endianness:
Endianness describes the order in which a sequence of bytes are stored in computer systems memory. The two most common types are: Big-Endian (also known as BE) and Little-Endian (also known as LE).
In the Big-Endian order the "big end" of the number (most significant value in the sequence) is stored first (placed at the lowest address). In the image below you see the number
0x12345678stored at the address
0x100in the big-endian order. Notice that the most significant byte
0x12is at the address
In the Little-Endian order the "little end" of the number (least significant value in the sequence) is stored first. In the image below you see the number
0x12345678stored at the address
0x100in the little-endian order. Notice that the least significant byte
0x78is at the address
Values that need more then 8-bits (in other words: larger than 255) have to be stored in multiple bytes. However, the emulated systems we use store multi-byte values in little-endian order.
In the image of the Memory Viewer above you can see that at address
0x0002c0 we have the hex value
ce and in
0x0002c1 the value is
39. When you switch the viewer to 16-bit mode, the
39 values are grouped at
0x0002c0 and get displayed as
39ce. This happens because it automatically groups every two bytes and displays them as 16-bit hex values.
NOTE: While 16-bit values are usually aligned to even addresses, that's not always the case. There's actually a non-displayed 16-bit value at
0x0002c1. Since the value at
39 and the value at
29, the 16-bit value at
0x0002c1 address is
Similarly, in 32-bit mode, the four bytes from
0x0002c3 are displayed as a single 32-bit value
0x252939ce at address
0x0002c0, but there are also 32-bit values at
Working with sizes smaller than 8-bit
In addition to the 8-bit, 16-bit and 32-bit sizes described above, there are additional sizes that can be used when writing achievements (in the Achievement Editor).
In the memory viewer when an 8-bit address is selected you will see something like the image below (in the image: a byte with the value
6f is selected; the bits are highlighted with an orange circle):
It is very common in games to store important information as a single bit. As a bit can only have two possible values (
0), sometimes it's used to mean "yes" or "no", "on" or "off", "have item" or "no item", etc. Some games, specially those with limited memory space, use bit switches a lot.
Important: You can refer to each one of those bits individually in the Achievement Editor.
Common meaning of bit switches in a game memory:
- have an item
- button pressed (very common)
- area explored
- in game trigger activated
- cheat activated
- in demo mode
In the memory viewer you can only input hex values, then it's important to know equivalence of values between hex and binary notations. You can see the table in the "Decimal, Binary and Hexadecimal notations" section, but the usual is to use a calculator (the default calculator on MS Windows on the programmer view can do the job).
Upper4 and Lower4
Upper4 is the upper four bits of a byte (bit: 7, 6, 5, 4), displayed as a single hexadecimal character. Lower4 is the lower four bits of a byte (bit: 3, 2, 1, 0), displayed as a single hexadecimal character.
Looking at the memory size diagram below, a byte at address
0x00a274 is selected (value
0x23). The first character,
2 is the Upper4 value. The second character
3 is the Lower4 value.
Occasionally you will only be interested working with a single hexadecimal digit. Using the memory size diagram as an example, an achievement condition where
Upper4 0x00a274 = 0x2 would be true. A condition where
Lower4 0x00a274 = 0x3 would be true.
Memory Sizes diagram