-
Notifications
You must be signed in to change notification settings - Fork 10
Code Notes
Code notes are a vital part of achievement development. They provide valuable context to memory addresses used in achievement creation. Good code notes can make future achievement troubleshooting a breeze for developers, while bad code notes can make it a nightmare. This guide will help developers create clear, helpful, and consistent code notes that can be used by any developer looking at their sets in the future.
Code notes are made by the developer in the Memory Inspector as they are RAM digging a game. This allows for easily seeing where sizes of notable addresses as well as areas in the RAM that hold important values. Code notes can be added, deleted and updated from the Memory Inspector. Code notes that are already created can be updated or deleted from the games' "Code Notes" page on the website. This is intended for quick fixes to notes and not intended as the main form of code note modification.
- Developers are free to add any code notes to any game without declaring intentions to work on the game. Just be careful to not delete previous notes added by someone else unless you are certain they are incorrect.
- Junior Developers shall limit their code notes to the game they have claimed. Juniors are unable to delete or overwrite notes made by other users.
- Be Clear and Informative: Code notes should clearly document what the address represents such that it can easily be understood by other developers.
- Specify the Address Size: Code notes should specify the size of the address being noted. This helps to easily know the address size during achievement logic creation and also to correctly color the address values within the Memory Inspector.
- Include Important Values: Code notes should include all values that are used within the achievement logic. Undocumented values make debugging much more complicated, especially if you didn't create the note.
- Document Extensively: It's better to document any useful addresses that you find, even if you know you won't need them in the achievement logic. You never know what addresses may be needed later on if the set is revised.
There are multiple ways to specify a memory address that will be recognized by the Memory Inspector highlighting. Any code note that does not specify a valid size will cause the Memory Inspector to highlight the byte the note is for. Any number of bit and byte lengths will be recognized by the Memory Inspector highlighting. Many developers will enclose the address size in square brackets ([]
) to make it more noticeable in the full note.
-
[Lower4]
,[Upper4]
-
[8-bit]
,[16-bit]
,[24-bit BE]
,[32-bit]
,[Float]
-
[1 byte]
,[2 bytes]
,[4 bytes]
,[8-bytes]
-
[128 bits]
,[78 bytes]
,[428 bits]
,[1024 bytes]
Very often you will run into an address that uses each bit within the address to store data. Noting the individual bits won't affect any Memory Inspector highlighting, though each bit should be properly noted in the code note. Some people choose to mark the size for these as [Bitfield] or [Bitflags] instead of [8-Bit].
When you need to label specific values or bit meanings in a note, here are some things to keep in mind.
- Always prefix hexadecimal values with
0x
so that it is clear the value is in hex. This is especially important if none of your values use characters A-F. - If values are in decimal, consider putting a note in the description to this effect:
(Values below are decimal)
- Put each value on a separate line - This is usually the easiest way to visually distinguish each value. You should usually use this when there are more than two values to label.
- If there are only two values (Example: Yes/No), consider placing them inline with the description, if the description and labels are short.
- Put a separator between the value and its label. This can be an equals sign, a colon, or a dash, and you may put whitespace as needed. Tip: Using an equals sign without spaces lets you easily copy the value list into a Rich Presence lookup.
Simple address types cover the very basic address that are needed for nearly every achievement set and are often the some of first addresses noted when RAM digging. Often easily described in a line or two. These may include health, lives, in game currency, level, X/Y positions, etc...
Good examples here include size, description, and different values or affects on the values.
[8-bit] Difficulty
0x01 - Easy
0x02 - Normal
0x03 - Hard
[16-bit] Player Health
Max health is 0x1200, each hit reduces it by 0x8
Difficulty
health
Map and Screen ID type code notes are very often used to determine location within the game and commonly used in level completion or item collection achievements.
Good examples here include the various values that the address can take throughout the game. All addresses used in the achievement logic are noted in detail.
[8-bit] Screen ID
Chapter I
0x36 - Initial Screen with woman's face
0x0b - Taxi ride opening scene
0x07 - Outside of apartment (Day 1)
0x04 - Apartment main hall (Day 1)
0x16 - Apartment main hall (Day 2)
Chapter II
0x37 - Driving intro cutscene
0x2b - Outside of Inn (Day 1)
0x2c - Inn main room (Day 1)
screen id
There are numerous way a game can store the players scores with memory, as such there are numerous ways to write the score code note out.
Good examples here will specify the size, which digits of the score are being represented, how the on screen score is calculated from the value in memory, Binary Coded Decimal (BCD) notation if applicable, as well any any other important details.
[1 byte] 1P display score, digits 0000XX00 in BCD
[16bit][DEC] P2 Score XXXX0000
Score [24-Bit BE BCD] (Determines Rank)
0-9=Pauper
0-99=Peasant
100-999=Prosperous
1000+=Professional
Player 1 score
It's very common to run into games that need to store event or item flags. Often these will be stored as individual bits rather than taking up an entire byte per flag. It's assumed that a bit value of 0 is off/no/false, if this is not the case then that should be noted.
Good examples here will specify each bit as well as what they represent.
[Bitflags] Requests completed
Bit1 = No. 01 - Retrieve 1 Beetle Shell.
Bit2 = No. 02 - Retrieve the first old document.
Bit3 = No. 03 - I'd like to sip a Muscle Drink.
Bit4 = No. 04 - Retrieve 3 Old Lanterns.
Bit5 = No. 05 - Retrieve the second old document.
Bit6 = No. 06 - Create Jack Frost with Dia.
Bit7 = No. 07 - Retrieve 1 Lead Metal.
Bonuses Unlocked
bit0 - All Replay Items
bit1 - Unlimited Ammo (Mission 1)
bit2 - Silver Bullets (Mission 3)
bit3 - Bullet Shield (Mission 4)
bit4 - Rubber Grenades
bit5 - Men With Hats (Mission 5)
bit6 - Always Sniper
bit7 - Achilles Head (Mission 6)
[Treasure Flags 03]
Bit0=[Altair - Rebel Hideout] Potion
Bit1=[Fynn - Pub Basement] Scott's Ring
Bit2=[Castle Deist 1F - South Treasure Room] Stun Tome
Bit3=[Castle Deist 1F - South Treasure Room] Stop Tome
Bit4=[Castle Deist 1F - South Treasure Room] Curse Tome
Bit5=[Cave of Mysidia B4 - Treasure Room] Bell of Silence
Bit6=[Castle Deist 1F] Phoenix Down
Bit7=[Castle Deist 1F - NW Treasure Room] Gold Needle
The bits here represent the unlocked bonuses
Pointers are more commonly found in newer consoles and their notes typically include information for various addresses that the pointer can point to. The pointer notes will typically include numerous offset values to the important addresses used by the developer.
- If offsets with labels are written correctly, the memory inspector and assets editor will generate indirect code notes at the pointer address + offset of the correct size.
- Use a plus sign
+
before the offset value.- For pointers with multiple layers, many people will use additional pluses to indicate that it is an offset of a pointer being pointed to by the original pointer. However, this will break all indirect code notes for that pointer. Consider using a vertical pipe before these layered offsets instead to allow for the top layer to generate indirect code notes.
- Use
0x
to indicate a hexadecimal offset value; the memory inspector will treat it as a decimal offset if this is not present. - You can separate the offset value and its label with any number of spaces, and a separator character like an equals sign, a colon, or a vertical pipe.
- You should specify the size of the data at the offset like any normal code note. Indirect notes and highlighting will use this.
- If multiple lines are present after the offset value, they will all be part of the indirect note for that address.
Good examples here will include various address offsets, each of which including details and size of the address being pointed to.
Pointer to P1 Data [16-Bit]
+0x68 P1 Character ID [8-Bit]
+0xba P1 Health [8-Bit]
+0xc4 P1 Move ID [16-Bit]
[32-bit] Data Pointer
+0x638 | Pointer to pointer to smells pointer
++0x6d0 | Pointer to woofs
+++0xb8 | Total Woofs [32-bit]
+++0x380 | Sniff Level [32-bit]
0x00 = Sniff Apprentice
0x01 = Sniff Artisan
0x02 = Sniff Expert
0x03 = Sniff Master
0x04 = Grand Sniff Master
+++0x3c8 | Pointer to Racing Data [32-bit]
++++0x15a8 | Checkpoint Count [32-bit]
++++0x15ac | Frame Timer [32-bit]
++0x13d8 | Pointer to smells pointer
+++0x04 | Total Smells [32-bit]
*US* Pointer [32-bits]
--Player Kratos--
+0x97898=Health [Float]
+0x6f570=Combo [32-bits]
+0x977a0=Coordinates Y [Float]
+0x977a4=Coordinates Z [Float]
+0x977a8=Coordinates X [Float]
--Unlockables (Alternative)--
+0x6f594=Poseidon's Trident [Bit0]
+0x6f598=Poseidon's Rage [Bit0]
+0x6f59c=Medusa's Gaze [Bit0]
+0x6f5a0=Zeus' Fury [Bit0]
+0x6f5a4=Army of Hades [Bit0]
+0x6f5a8=Blade of Artemis [Bit0]
Pointer for player information. Includes player data and unlockables.
- User Guidelines
- Developer Guidelines
- Content Guidelines
- FAQ
- Setup Guide
- Emulator Support and Issues
- Ways to Contribute
- RABot, the RA Discord Robot
- Events
- Overlay Themes
- Useful Links
- Contributing with the docs
- About Us
- Tutorials
- Developer Docs
- How to Become an Achievement Developer
- Getting Started as an Achievement Developer
- Game Identification
- Achievement Design
- Achievement Scoring
- Difficulty Scale and Balance
- Progression and Win Condition Typing
- Badge and Icon Creation
- Achievement Development Overview
- Flags
- BitCount Size
- Alt Groups
- Hit Counts
- Delta Values
- Prior Values
- Value Definition
- Condition Syntax
- Minimum Required Versions for Logic Features
- Memory Inspector
- Real Examples
- Set Development Roadmap
- Achievement Templates
- Tips and Tricks
- Leaderboards
- Rich Presence
- RATools
- Console Specific Tips
- Emulator Hotkeys for Developers
- libretro core support
- Docs To Do List
- WIP User Code of Conduct
- WIP CoC FAQ
- WIP Content Guidelines
- WIP-Jr
- WIP---Dev-Tips---Code-Notes-En-Masse
- WIP-‐-Reauthorship-Policy
- Manifesto RetroAchievements
- Código de Conduta do Usuário
- FAQ - Perguntas Frequentes
- Como contribuir se você não é um desenvolvedor
- Tutorial para Jogos Multi-Discos
- Introdução
- Primeiros Passos como um Desenvolvedor de Conquistas
- Recursos de Lógica para Achievements
- Exemplos Reais
- Dicas e Truques
- Dicas Específicas de Console
- Modelos de Achievement
- Escala de Dificuldade e Equilíbrio
- Roteiro de Desenvolvimento de um Set de Conquistas
- Criação de Ícones e Emblemas
- Leaderboards
- Rich Presence
- Design de Conquistas
- Manifesto RetroAchievements
- Código de Conducta del Usuario
- FAQ - Preguntas Frecuentes
- Tablas Globales y Reglas para la Casería de Logros
- Mi juego no esta cargando los logros
- Como contribuir si no eres un desarrollador
- Por que no deberías utilizar la función de cargar estado
- Contribuyendo con los documentos
- Como funciona la Documentación de RA
- Descargas
- Intro
- Código de Conducta del Desarrollador
- Como convertirme en un Desarrollador de Logros
- Primeros pasos como un Desarrollador de Logros
- Un vistazo al Inspector de Memoria
- Características en la Logica de un Logro
- Ejemplos Reales
- Intro
- Utilizando Hit Counts como un Temporizador
- Utilizando Valores Delta y Hit Counts para Detectar un Incremento
- Un Ejemplo Simple en como evitar el Abuso de Estados de Guardado
- Evitar el Problema de que un Contador se Incremente Dos Veces en el Mismo Frame
- Creando un Temporizador con un ResetIf Hits basándote en la Velocidad de un Juego
- Plantillas para Logros
- Tips y Trucos
- Escala de Dificultad y Balance
- Diseño de Logros
- Mapa de Desarrollo de Set
- Revisiones en Set de Logros
- Creación de Iconos y Badges
- Tablas de Clasificación
- Rich Presence
- Trabajando con el ROM apropiado
- Identificación del Juego
- Guía para Sets Bonus
- Logros para ROM hacks
- Tips Específicos por Consola