๐Achievements
More than a trophy
Last updated
More than a trophy
Last updated
Consider supporting us as a GitHub Sponsor and get instant access to all our Unity assets, exclusive tools and assets, escalated support and issue tracking and our gratitude. These articles are made possible by our GitHub Sponsors ... become a sponsor today!
Achievements are a simple and traditional feature for games that can help drive player engagement. They can also act as a poor-mans Game Statistics feature, for example, you can set achievements to unlock at particular milestones and then monitor the game's global stats to see what % of your player base has unlocked each achievement giving an idea of how your game's retention looks.
First, you need to create your achievements on the Steam Developer portal. https://partner.steamgames.com/
Log into your Steam Developer Portal and access your app's admin page. Look for the Technical Tools section and select the Edit Steamworks Settings option.
From there select the Stats & Achievements > Achievements option and create your new achievements.
Make note of the value you use in the API Name field. You will use it when working with achievements in code.
In Unity, if you prefer to work with Achievements via an object reference then you can use our AchievementObject which is a Unity ScriptableObject that can be referenced and accessed like any other Unity Object.
You **MUST** publish your changes in Steam Developer Portal before they will be accessible via Steam API. In the Steam Developer Portal when you have pending changes you will see a red banner at the top of the screen ... click it and follow the instructions.
The first thing to understand is that with stats and achievements, the process of setting them in two steps.
You assign the value
You store the changes in the backend
Understand that not every game needs achievements, that if you're going to have achievements they should be part of the game and not an afterthought you bolted on because why not? Meaningless achievements can harm the user experience by breaking immersion or simply drawing attention away during gameplay.
Following are some ideas for meaningful achievements and how you might tie those achievements into other aspects of your game.
This is the process of committing any changes made during gameplay to the Steam backend. That is you can freely "set" the state of achievements and stats during gameplay such as incrementing kills of enemy units, player score, etc. These changes are written to the local cash, not directly to the backend.
When the game is closed or when you call "Store" the changes will be committed to the backend. This should be done at key points in the game such as at the end of a level, on player death, when a boss is defeated or at some other opportune time. It is generally not recommended that you constantly call Store() with each change.
Think about when you want that popup to show It will be immersion-breaking, it could cover parts of the screen, and it could cause things such as Windows Auto HDR to cause screen flicker ... in generally you want it to show only when the player is not actively engaged in gameplay such as on a menu, debriefing, "You Died" screen, etc.
There are several ways to store stats and achievements and they all do the same thing. They are simply different ways you can trigger the effect depending on what objects you have available in memory and how you are more comfortable as a developer.
The Steam popup that you're used to seeing when you unlock an achievement or receive some other notification is not code in the game but rather the Steam client rendering overtop the game's window.
Players can force this to be disabled so do not assume it will always be present it's the user's choice as configured in the Steam client, not your game. This is not for you to control.
For achievements, this popup triggers when an achievement is stored not when it is set. Also, note that because it is rendering over the game window it will not likely work properly when testing in the Unity Editor or if you have a debugger or other app mounted to the process as this may restrict window updates and or add additional windows to the process.
Think of your achievements like a meta quest ...
Meta means beyond or above, etc. and when we use it we mean a concept, information, etc. that is not part of the main but additional and external to it.
Like a meta quest, that is a quest for the player (not the character in-game world) to learn your game. To encourage them to explore the features and functions of your game in a structured manner and to offer some non-gameplay impacting rewards for doing so.
For a practical example of this see DOTA 2's "New Player Experience" aka "Welcome Quests" where they present "quests" for new players to do simple things like open menus, use features, review information, play each of the game modes, etc. Importantly this is not hidden from the player it's presented to the player in the menu just like a quest, showing what steps are yet to be done and which have been done.
The best tutorials are fun and engaging parts of the game that happen to also teach the player mechanics, concepts, demonstrate tactics and strategies and more. Similar to the New Player Experience approach you can use Achievements as a means to draw attention to these instructions and reward their completion without forcing the player into them.
Steam Inventory is a huge topic unto itself that needs its own guide. The overlay with Achievements is that you can restrict eligibility for Item Promotion drops based on unlocked achievements. You can use this with New Player Experience or Tutorial style achievements to award in-game items for completing the tasks.
There are many types of players and a common one across all game genres is the "Collector" or "Hunter" This is a type of player that likes to "100%" the game. Be careful to not bloat your game with meaningless achievements as this will simply frustrate the collector but do make sure to track and reward them for fully exploring your game.
Did you know you can view the global stats for games that have achievements seeing what % of the player base has achieved each achievement?
Well now you do, this means you can use achievements to understand (vaguely) what parts of your game are used and what are not, used well and you can track where players "fall off".
Steam Stats and Achievements provides an easy way for your game to provide persistent, roaming achievement and statistics tracking for your users. The user's data is associated with their Steam account, and each user's achievements and statistics can be formatted and displayed in their Steam Community Profile.
Achievements like stats are created in your Steam Developer Portal, once created there you can access them via their ID, if you are not using Heathen's Steamworks ... why aren't you, it has a free version. Then you can import your Stats and Achievements into Unity or use our AchievementData structure to easily work with your achievements in code.
Valve's documentation on the Stats and Achievement features is a good place to get started.
Setting an achievement is a 2 step process, you first "set" the achievement that is you mark it to be "unlocked". This step can be done in real-time as your game plays and even calls multiple times a frame with no adverse impact on performance as this is NOT calling the backend at all, it simply records locally that this achievement should be set.
Then at an appropriate time for your game such as at the end of a boss fight, on player death, end of a mission, before or after a cut scene, etc. you would call "Store" aka "Store Stats". This will cause Steam to commit the changes for all stats and achievements to the backend. It is at this time that notifications are poped up. This should NOT be called rapidly such as with every frame, it should only be called at key points in your game.
You can drag and drop your achievements from the Steam Settings object you wish to use to anything able to set a field or call a method. For example the On Value Changed event of a Unity UI toggle
You could optionally also have it call Store committing the change to the backend at the same time.
This assumes myAch is an AchievementObject or AchievementData
Typically when "reading" an achievement you are simply checking if the achievement is "achieved" aka "unlocked" for the user and this is a simple boolean value. You can however read additional information such as when it was unlocked, you can also get the current "icon" for the achievement which will be either the locked or unlocked version depending on if the user has achieved this achievement.
You can read the Is Achieved value from the Scriptable Object in the same manner as setting it (see the Set Achievement above)
You can also get the icon, name and description of an achievement without writing any code.
This assumes myAch is an AchievementObject or AchievementData
This is just setting the IsAchieved field to false, see the Set Achievement example.
This assumes myAch is an AchievementObject or AchievementData
You can drag and drop your achievement from the Steam Setting object to anything that can call a function such as a Unity Event, and then select Store as the function of the field to be invoked.
This assumes myAch is an AchievementObject or AchievementData