Skip to content

RetroAchievements website

RA discord server

Rich Presence


Rich Presence (RP) is brief overview of what active players are currently doing in their game. To have RP in a game you need a Rich Presence Script (RPS) which is created by Developers. The Script check the player's game memory and as programmed reports the values of certain addresses with definitions assigned by the Developer such as which stage the player is on, how many lives they have, if the game is paused, what game mode they are playing, what the player has accomplished, etc. This information is reported back to the website. Every game published should have at least a basic RPS.

Example of RP in action:

Example of RP in action

To see the RP live in a game click on the RetroAchievements menu in your emulator and then click on Rich Presence Monitor. A small window will show you your active RP. (Good for debugging)

Rich Presence Monitor

The best way to understand Rich Presence is to look at various examples in game, look at the addresses used and look at how the text is displayed in the Rich Presence Monitor and on site.

How Does it work?link

Every time a game is launched, it fetches the achievements in a 'patch' file for the ROM which details all the achievements and memory addresses (and leaderboards) that can be watched for. It will also request a Rich Presence Script for the currently loaded ROM. The emulator will report back to the website every 120 seconds. Similarly, every 120 seconds or so, the 'active players' box on the frontpage will refresh, detailing the last known activity of all active players. If there isn't a rich presence script given, the text will be 'earning achievements' if playing a game with achievements, 'playing [game]' if playing a game without achievements, or 'developing achievements' if the memory dialog is open and visible.

The RPS for each game can be found under the development section on each game's page:

Dev click

RP shown

Example (Super Mario Bros.)link


2=[World Complete] 




1= swimming

0= [Loading]
1= taking a vine warp
2= entering a warp pipe
3= entering a warp pipe
4= 🚩
5= [Stage Complete]
6= [Game Over]
7= [Entering Area]
9= growing
0xA= shrinking
0xB= 💀
0xC= powering up


@Mode(0xh770)@Paused(0xh776)@Star(0xM79f_0xN79f_0xo79f_0xP79f_0xQ79f_0xR79f)@Powerup(0xh0756) Mario in @Digit(0xh75f_v1)-@Digit(0xh75c_v1)@Swimming(0xh704)@Status(0xhe), 🚶:@Digit(0xh75a_v1), @Quest(0xh7fc) Quest

It breaks down into a series of Lookup objects, Format objects and one Display object.


Lookups are defined like this:

Value1=Text When This Value
Value2=Text When Another Value

We give the Lookup a value, consisting of a series of memory addresses and modifiers. More about this later.


Format tables are defined like this:


Begin with Format:, then the name of the format type. On the next line, give FormatType=, then one of the following: VALUE, SCORE (or POINTS), TIME (or FRAMES), SECS, MILLISECS, or OTHER.

  • VALUE: generic value, no leading zeroes.
  • SCORE/POINTS: "000130 points"
  • TIME/FRAMES: value describes the number of frames elapsed, and will be turned into 00:00.00
  • SECS: value describes the number of seconds elapsed, and will be turned into 00:00
  • MILLISECS: value describes the number of millisecs elapsed, and will be turned into 00:00.00


Display will be a string that gets shown in the 'Active Players' box on the front page. It refers to the previously defined Lookup and Format objects using a single '@'. It then specifies a name for the lookup or format (case sensitive!), and immediately after, in brackets, a series of memory values specifying what to send to that lookup or format object.


This means use the Lookup or Format that's called Powerup, and give it whatever value is in 0xh756.

Example Lookup Breakdownlink

  • @Mode(0xh770) - Lookup for the address that shows if the game is in demo mode or a world has been completed.
  • @Paused(0xh776) - Lookup for the address that shows if the game is paused (3 values are used, two of them are for pausing and unpausing).
  • @Star(0xM79f_0xN79f_0xo79f_0xP79f_0xQ79f_0xR79f) - Lookup for the address of if Mario has Star invincibility. More on this later.
  • @Powerup(0xh756) - Lookup for the address that show if Mairo is Small, big or has fire power.
  • Mario in - Static text to string lookup and format objects together.
  • @Digit(0xh75f_v1) - Digit is a format object defined as a value. The address 0xh75f is the World minus 1 (because it it 0 based, as in it starts counting at 0). _v1 Means + value 1. _v+1 is also correct.
  • - - More static text to split World and Level. as in the hypen in World 1-1.
  • @Digit(0xh75c_v1) - Another use of the Digit format object. This time It's looking up the stage. World 1-X.
  • @Swimming(0xh704) - Lookup for the address that shows if the player is swimming.
  • @Status(0xhe) - Lookup for the address that shows Mario's status, such as going through pipes.
  • , 🚶: - More static text. 🚶 is a symbol for lives.
  • @Digit(0xh75a_v1) - Third use of the Digit format object. This time it's checking the player lives address.
  • , - Static text.
  • @Quest(0xh7fc) A lookup to see if the player is in normal or on the 2nd quest, hardmode.
  • Quest - Static Text.

Address sizelink

To specify what size of address you are are checking there are various characters used. (capitalization is ignored)

  • A 16bit address is default and has no character designation. At 0x10 the address is two bytes - 16 bits.
  • An 8bit address's character is h (or H). At 0xh10 the address is one byte - 8 bits. xxxx xxxx
  • An upper4 address's character is u (or U). At 0xu10 the address is one nibble - 4 bits. xxxx 0000
  • A lower4 address's character is l (or L). At 0xl10 the address is one nibble - 4 bits. 0000 xxxx
  • A bit0 address's character is m (or M). At 0xm10 the address is one bit, the lowest bit: 0000 000x
  • A bit1 address's character is n (or N). At 0xn10 the address is one bit, the second bit: 0000 00x0
  • A bit2 address's character is o (or O). At 0xn10 the address is one bit, the third bit: 0000 0x00
  • A bit3 address's character is p (or P). At 0xp10 the address is one bit, the fourth bit: 0000 x000
  • A bit4 address's character is q (or Q). At 0xq10 the address is one bit, the fifth bit: 000x 0000
  • A bit5 address's character is r (or R). At 0xr10 the address is one bit, the sixth bit: 00x0 0000
  • A bit6 address's character is s (or S). At 0xs10 the address is one bit, the seventh bit: 0x00 0000
  • A bit7 address's character is t (or T). At 0xt10 the address is one bit, the top bit: x000 0000
  • A 32bit address's character is x (or X). At 0xx10 the address is four bytes and 32 bits.

Summarizing on a table:

location/size prefix (the letters can be in lower case) example
bit0 0xM 0xM01234
bit1 0xN 0xN01234
bit2 0xO 0xO01234
bit3 0xP 0xP01234
bit4 0xQ 0xQ01234
bit5 0xR 0xR01234
bit6 0xS 0xS01234
bit7 0xT 0xT01234
Lower4 0xL 0xL01234
Upper4 0xU 0xU01234
8bit 0xH 0xH01234
16bit 0x 0x01234
32bit 0xX 0xX01234

Conditional Display Stringslink

?0x 000085=0?Title Screen
?0xT00007c=1?Custom Map in @Landscape(0xH00016c)
Playing Battle @Battle(0x 00007c*0.2) in @Landscape(0xH00016c)

The existing Display: marker is still used to indicate the start of the display block. If the next line starts with a question mark, it is considered to be a conditional display string. The portion of the line between the two question marks is the conditional clause. If the conditional clause evaluates true, then the remaining portion of the line is used as the display string. If it does not evaluate true, then processing proceeds to the next line. If it starts with a question mark, the same process repeats. If it does not start with a question mark, the entire line is used as the default display string.

Looking at this example, if the 16-bit value at $0085 is 0, the display string is Title Screen. If not, the next line is examined. If the 7th bit of $007C is 1, the display string is Custom Map in @Landscape(0xH00016c). If not, the final line does not have a conditional clause and is used.

Display strings associated with a conditional clause support all of the same syntax as the default display string. In this example, you can see the @Landscape lookup is used in both the conditional display string and the default display string. The lookup itself only has to be defined once.

The conditional phrase supports all of the previously mentioned address accessors as well as AND (_) and OR (S) logic. Note that OR clauses still require a 'core' group, just like achievements.

  • ?0xH1234=32_0xH2345=0?and example

    if the 8-bit value at $1234 is 32 and the 8-bit value at $2345 is 0, display and example

  • ?0xH1234=32_0xH2345=1S0xH2345=2?or example

    if the 8-bit value at $1234 is 32 and the 8-bit value at $2345 is 1 or 2, display or example

Binary Coded Decimal (BCD)link

BCD is when the values are store in an address from as 0-9 (one digit) or 0-99 (two digits). Keep in most often values are stored in hexidecimal, but sometime games will store them in this way and here's the best way to handle these addresses in your display.

For value objects you can use the BCD prefix, as in b0x1. A BCD address is assumed to be 8bit, h is unnecessary but also won't cause problems. Other character prefixes work? (untested). When you use the b prefix and the address is stored as a BCD your out put for an address that is 10 will be 10 instead of 16 (which is 10 in hex).

This is most commonly used for score and time, but often other types of display values.


  • 2500 character limit for script
  • 100 character limit for what is displayed
  • Unicode characters are allowed
  • Using & in text will cut off the script after the &
  • Using the character + Will not display

Syntax Detailslink

  • The RPS ignores trailing 0s in hex address lookups and values 0x00001 == 0x1, 0xh0000245 == 0xh245, 0x0a == 0xa.
  • Lookup values are Decimal by default and hex if you place the prefix of 0x. This mean 1 == 0x1, 2 == 0x2, 9 == 0x9, 10 == 0xa, 100 == 0x64, etc.

Tips and Trickslink

  • Lookups must be case specific with their corresponding @ in the display and not contain spaces after the lookup is defined.
  • Lookup names can be as short as a single character if you need to squeeze in a few extra characters.
  • Turning all your values from hex into decimal will take up less characters.
  • Unicode characters don't always "take up less space" they often take up to four system characters.
  • If you do not define your lookups they will be left blank (no space). This is only true for NES, SNES, Gen, RAVBA. N64, Meka and Lynx will leave the word "Unknown" each time you don't define a lookup.
  • You only need one value format object. You can reference it with multiple addresses. (is this always true?)
  • Putting spaces in your lookups sometimes before or after can allow you to hide certain lookups when they are not needed, like how @Pause, @Star, @Swimming, and @Mode do.

Value Propertieslink

When using lookup and format objects @object() it's possible to combine and perform calculations. This can be used to correctly display a score, in game time, etc. or make more advanced lookups.

Example @Score(0x28*10_0x29*1000_0x26*100000) points

This means use the Lookup or Format Score, and give it the sum of:
- 0x28 times 10, ADD
- 0x29 times 1000, ADD
- 0x26 times 100000

  • _ adds the addresses together.
  • Or you can add a static value 0x28_v10. This adds 10 to your total, as in whatever the value of 0x28 + 10 will be displayed. You can also subtract 0x28_v-10.
  • If you'd like to subtract an address you need to multiply the address by -1. 0x29*-1. 0x29 is now negative.
  • If you'd like to perform division you'll need to multiply by a decimal. 0x26*.5. 0x26 will output 1/2 of the value at 0x26.
  • And you can string everything together: 0x28*10_0x29*-1_0x26*.625_v-10.
  • You can also add addresses together to give you lookups based on the sums of various addresses. This is used in the example in @Star. It's looking up sum the 6 lowest bits of the address 0xh79f. The way this address works is that so long as there is a value there Mario is invincible star mario and it counts down from hex value 0x23 (35 decimal) to 0. 23 in binary is 0010 0011 meaning the max sum of these bits could 5 during 0001 1111 when the count down reaches hex value 0x1f (31 decimal).

Unicode Standard Symbolslink

🔁=Loop number
🚶=Lives. Other symbols that represent the game clearly are also suitable. 🐰=in a Bugs bunny Game, 🐵=in a Donkey Kong Country game, ✈=In a jet plane game,
⏰=In Game Time/Game Clock
💣=Bombs ☰=Menu
❤️ or ❤=In a game with hearts (e.g. Zelda)