A cross-platform achievement system for Godot 4+ with C#/.NET support. Abstracts platform-specific achievement APIs behind a unified interface, making it easy to ship to Steam, iOS, and Android with a single codebase.
- โจ Features
- ๐ฎ Supported Platforms
- ๐ฆ Installation
- ๐ Quick Start
- ๐ ๏ธ Setup Achievements in the Editor
- โ๏ธ Enable Different Providers
- ๐ง Adding a Custom Provider
- ๐ค Contributing
- ๐ Roadmap
- Cross-platform abstraction - Single API for Local, Steam, Game Center, Google Play, and custom providers
- Visual editor - Manage achievements from a dedicated editor dock
- Built-in toast notifications - Configurable unlock notifications with custom scene support
- Local-first persistence - Achievements saved locally, synced to platforms (on unlock + on launch)
- Progress tracking - Support for incremental/progressive achievements
- Extensible - Add custom providers by implementing a simple interface
| Platform | Provider | Required Addon |
|---|---|---|
| Local/Offline | LocalAchievementProvider |
Built-in |
| Steam | SteamAchievementProvider |
Godot.Steamworks.NET |
| iOS Game Center | GameCenterAchievementProvider |
GodotApplePlugins |
| Google Play | GooglePlayAchievementProvider |
godot-play-game-services |
- Copy the
Demo/addons/Godot.Achievements.Netfolder to your project'saddons/directory - Build the project
- Enable the plugin in Project > Project Settings > Plugins
๐ก Tip: It might help to reload the project before continuing to setting up your achievements
// Unlock an achievement
AchievementManager.Instance.Unlock("first_blood");
// For progressive achievements
achievements.IncrementProgress("kill_100_enemies", 1);AchievementManager.Instance.AchievementUnlocked += (id, achievement) => {
GD.Print($"Unlocked: {achievement.DisplayName}");
};Once the plugin is enabled, you'll find an Achievements dock at the bottom of the editor (next to Output, Debugger, etc.).
- Click the + button in the dock to add a new achievement
- Fill in the required fields:
- Internal ID - Unique identifier used in code (e.g.,
first_blood) - Display Name - Player-facing name shown in toasts and UI
- Description - What the player did to earn it
- Icon - Optional texture for toast notifications
- Internal ID - Unique identifier used in code (e.g.,
For achievements that require multiple steps (e.g., "Kill 100 enemies"):
- Check Incremental in the achievement details
- Set Max Progress to the target value
- Use
IncrementProgress()in code instead ofUnlock()
When you enable a platform provider, additional fields appear in the editor:
- Steam ID / Steam Stat ID - IDs from your Steamworks dashboard
- Game Center ID - Achievement ID from App Store Connect
- Google Play ID - Achievement ID from Google Play Console
The editor validates that enabled platforms have their IDs filled in and shows warnings for missing values.
Custom properties let you store additional metadata on achievements, such as IDs for unsupported platforms or game-specific data.
Key behavior: Custom properties are shared across all achievements as a schema. When you add a property to one achievement, it appears on every achievement in your database.
- Click Add Property to create a new property key
- Set the value type (string, int, float, bool, etc.) using the type picker
- Rename a property key to rename it across all achievements
- Removing a property removes it from all achievements
This is particularly useful for custom providers - see Adding a Custom Provider.
๐ก Tip: You can even set a property to use Godot resources!
Use the import/export buttons to:
- Export achievements to JSON for backup or version control
- Import achievements from JSON or CSV files
Enable auto-generation in Project Settings > Addons > Achievements > Codegen to generate a C# constants class:
// Generated AchievementConstants.cs
public static class AchievementConstants
{
public static class Ids
{
public const string FirstBlood = "first_blood";
public const string Kill100Enemies = "kill_100_enemies";
}
}
// Usage - type-safe achievement references
AchievementManager.Instance.Unlock(AchievementConstants.Ids.FirstBlood);You can enable different built-in provider integrations via Project Settings > Addons > Achievements > Platforms:
| Setting | Description |
|---|---|
Steam Enabled |
Enable Steam achievements via Godot.Steamworks.NET |
GameCenter Enabled |
Enable iOS/macOS Game Center achievements |
GooglePlay Enabled |
Enable Google Play Games achievements |
The local provider is always active and serves as the source of truth. Platform providers sync achievements to/from their respective services.
Each provider requires its respective SDK addon to be installed and configured:
๐ฎ Steam:
- Install Godot.Steamworks.NET
- Initialize the SDK in your project (the addon provides a
GodotSteamworksautoload) - Enable
Steam Enabledin project settings for the achievements plugin
๐ Game Center (iOS/macOS):
- Install GodotApplePlugins
- Configure Game Center in App Store Connect
- Enable
GameCenter Enabledin project settings for the achievements plugin
๐ค Google Play Games:
- Install godot-play-game-services
- Configure your app in Google Play Console
- Enable
GooglePlay Enabledin project settings for the achievements plugin
Providers only initialize when their setting is enabled AND the SDK reports it's available at runtime. This allows the same build to gracefully handle missing SDKs.
If you need the plugin to work with a new provider (for example Epic Games, a console, etc.) that isn't officially supported, you can register one via the achievement manager by creating a class that implements IAchievementProvider or extends AchievementProviderBase:
public class MyPlatformProvider : AchievementProviderBase
{
public override string ProviderName => "MyPlatform";
public override bool IsAvailable => MyPlatformSDK.IsInitialized;
public override void UnlockAchievement(string achievementId)
{
var achievement = _database.GetById(achievementId);
var platformId = achievement?.MyPlatformId;
MyPlatformSDK.Unlock(platformId);
}
// Implement other required methods...
}To track the platform's ID, use the custom properties section in the editor UI.
โ ๏ธ Note: You will want to use preprocessor statements to make sure your game can cross-compile across different OSes. For the default providers this is done for you. See<Provider>.Stubs.csfor examples.
Contributions are welcome! Here's how you can help:
- Report bugs - Open an issue describing the problem and steps to reproduce
- Suggest features - Open an issue describing your idea and use case
- Submit PRs - Fork the repo, make your changes, and submit a pull request
- Documentation: Steam integration setup guide
- Documentation: Game Center integration setup guide
- Documentation: Google Play Games integration setup guide
- CI/CD examples for each supported OS/Provider
I'm building this plugin for my own upcoming game targeting Steam, iOS, and Android.
If this plugin helps your game, consider:
- โญ Starring this repo
- ๐ฎ Checking out my games on itch.io
This plugin was developed with assistance from generative AI tools. Plugin was architected, reviewed, and tested by humans.
MIT License - see LICENSE for details.
