Achievements
Author(s): benevolusgoatTags:
REPENTOGON article
This article focuses on working with REPENTOGON features.
Achievements can lock access to content in the game that must be unlocked to access, or exist for displaying milestones. This tutorial will cover how to create custom achievements and make use of them.
Adding custom achievements⚓︎
All custom achievements are defined in an achievements.xml file, located in the content folder at the root of your mod folder. In this folder, there must be a root achievements tag. This tag has a gfxroot property, which should point to the root directory of where your achievements are stored starting from your mod's resources folder. This is usually gfx/ui/achievement/, as that's where the vanilla game stores them.
1 2 3  |  | 
When defining a new achievement, you use an achievement tag alongside any of the available properties below. name is required while all others are optional.
achievement tag variables
| Variable Name | Possible Values | Description | 
|---|---|---|
| name | string | Required. Name of the achievement used for the GetAchievementIdByName function (when this is not present, text is used instead). | 
| text | string | Text description of the achievement. Has no functional purpose. | 
| gfxback | string | Path of the .png sprite to use as a background paper for the achievement. | 
| hidden | bool | Set to true to make it not show the achievement popup on unlock nor display the achievement in the secrets menu. | 
1 2 3  |  | 
Once added, you can go into the Secrets menu and view your mod's achievements by pressing up/down.

Unlocking/locking achievements⚓︎
With your achievement added, you can manage whether your achievement is locked or unlocked through the debug console or through Lua.
Debug console⚓︎
For the debug console, there's two commands: achievement and lockachievement. achievement will unlock any achievement in the game, while lockachievement locks it.

Lua⚓︎
Through Lua, your first step should be using Isaac.GetAchievementIdByName in order to obtain the ID for your achievement. Then, when you wish to unlock your achievement, using Isaac.GetPersistentGameData() will return a PersistentGameData object.
Two of PersistentGameData's functions will be used in this tutorial:
- TryUnlock attempts to unlock any given achievement. Can optionally be given an second argument that will block the paper pop-up while still unlocking the achievement, but only for modded achievements.
 - Unlocked Checks if the achievement is unlocked or not.
 
Locking achievements can be done through Isaac.ExecuteCommand and using the lockachievement command.
Loading achievements before a file is selected
Using PersistentGameData's functions before the game is loaded will modify a non-existent save file. TryUnlock will show the achievement unlocking, but will not unlock for any save files. Unlocked will always return false.
Only use these functions under callbacks that would run after the game has fully loaded.
This main.lua code will unlock the new achievement after collecting Sad Onion.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22  |  | 

Keep in mind that due to how the game handles achievement papers appearing, papers might not pop-up immediately and may require entering a new floor or ending a run. If the player has the "pop-ups" setting disabled, they won't see achievement papers at all.
Locking content behind achievements⚓︎
The most powerful utility of achievements is naturally locking modded content behind achievements. For any XML files that have an achievement variable available, you can insert the name of your achievement to prevent that content from appearing in normal gameplay unless the achievement was previously obtained.
The following XML files have an achievement variable available to utilize:
- items.xml for locking items and trinket.
 - pocketitems.xml for locking cards, runes, objects, and pills.
 - challenges.xml for locking challenges.
 - players.xml for locking characters.
 
challenges.xml achievement variables
challenges.xml is a special case with multiple achievement-related variables.
achievementsinstead ofachievementfor a comma-separated list of achievements, so that multiple can be required to unlock it.unlockachievementwill unlock the assigned achievement after the challenge is completed.lockeddesccan be used to show a special message while the achievement is locked instead of the default "LOCKED :("
This items.xml code will prevent this custom item from appearing in item pools until our achievement is unlocked.
1 2 3  |  |