.claude/skills/achievement-module/SKILL.md
AchievementModule reference — achievement tracking with composable unlock conditions, stat-driven progress, currency/stat rewards, Steam sync, game state gating, and reactive UI binding. Use when working with achievements, unlockables, or progression rewards.
npx skillsauth add punkfuncgames/tetris-clone achievement-moduleInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Package: com.punkfuncgames.achievement | Define: PUNKFUNC_ACHIEVEMENT
Location: Packages/com.punkfuncgames.achievement/Runtime/PunkFuncGames.Achievement/
Namespace: PunkFuncGames.Achievement
Registration:
Register(AchievementDefinition) — registers single definition, applies loaded save dataRegister(IEnumerable<AchievementDefinition>) — batch registrationUnregister(AchievementDefinition) — removes from tracking and indexesQueries:
bool IsUnlocked(AchievementDefinition/string) — check unlock statefloat GetProgress(AchievementDefinition/string) — returns 0-1 progress (1 if unlocked)ReadOnlyReactiveProperty<bool> ObserveUnlocked(string) — reactive unlock observationAchievementDefinition GetDefinition(string) — lookup by DisplayNameKeyIReadOnlyList<AchievementDefinition> GetAll() — all registeredIReadOnlyList<AchievementDefinition> GetUnlocked() — unlocked onlyIReadOnlyList<AchievementDefinition> GetLocked() — locked onlyIReadOnlyList<AchievementDefinition> GetByCategory(string) — filter by categoryint RegisteredCount — total registeredint UnlockedCount — total unlockedReadOnlyReactiveProperty<int> UnlockedCountReactive — reactive unlocked count for UI bindingEvaluation:
EvaluateAll() — force evaluate all achievements (gated by IsPlayable)UniTask SyncWithSteamAsync(CancellationToken) — bidirectional Steam syncAll events are readonly struct in PunkFuncGames.GameTemplate.Runtime.AchievementModule.Event:
| Event | Fields | Published When |
|-------|--------|---------------|
| AchievementUnlockedEvent | Achievement, UnlockedAt | Achievement unlocks |
| AchievementProgressChangedEvent | Achievement, NewProgress, PreviousProgress | Progress value changes |
[CreateAssetMenu(menuName = "PunkFuncGames/Achievement/Achievement Definition")]
| Field | Type | Purpose | |-------|------|---------| | DisplayNameKey | string | Localization key (auto-set from SO.name) | | DescriptionKey | string | Localization key (auto-set to name + "_desc") | | Category | string | Grouping: "Combat", "Exploration", etc. | | Icon | Sprite | Achievement icon | | Color | Color | Display color (default white) | | UnlockCondition | UnlockConditionConfig | Composable AND/OR/NOT condition | | IsProgressive | bool | Enables stat-driven progress tracking | | ProgressStat | StatsDefinition | Stat to track (DrawIf IsProgressive) | | ProgressTarget | SerializableBigDouble | Target value (DrawIf IsProgressive) | | SteamAchievementId | string | Steam API achievement name | | CurrencyRewards | AchievementCurrencyReward[] | Currency rewards on unlock | | StatRewards | AchievementStatReward[] | Stat rewards on unlock | | IsHidden | bool | Hidden from UI until unlocked | | SortOrder | int | Display ordering |
[CreateAssetMenu(menuName = "PunkFuncGames/Achievement/Achievement Database")]
Single source of truth — holds all AchievementDefinition[] for bulk registration. Serialized on ProjectLifetimeScope.
[Serializable]
public struct AchievementCurrencyReward
{
public CurrencyDefinition Currency;
public SerializableBigDouble Amount;
}
[Serializable]
public struct AchievementStatReward
{
public StatsDefinition Stat;
public SerializableBigDouble Amount;
}
Class: AchievementService : IAchievementService, IAsyncStartable, ITickable, IDisposable
Constructor Dependencies (11): ISaveService, ILogService (nullable), IStatsService, IWalletService, ISteamAchievementService, IGameStateService, IObjectResolver, AchievementDatabaseConfig, IPublisher<AchievementUnlockedEvent>, IPublisher<AchievementProgressChangedEvent>, ISubscriber<StatChangedEvent>
Key Behaviors:
IGameStateService.IsPlayable is falseStatChangedEvent triggers O(1) lookup via progressive indexTick()IsUnlocked check prevents re-unlock when stat rewards trigger new eventsCurrencyChangeSource.Reward + StatChangeSource.AchievementProgress Calculation:
Clamp01(statsService.GetValue(ProgressStat) / ProgressTarget)UnlockCondition.GetProgress(_objectResolver)0fProgressTarget <= BigDouble.Zero → 0fUnlock Decision:
UnlockCondition != null and not met → falseprogress < 1f → falsepublic static class AchievementInstaller
{
public static void Install(IContainerBuilder builder, MessagePipeOptions options)
{
builder.RegisterEntryPoint<AchievementService>().As<IAchievementService>();
builder.RegisterMessageBroker<AchievementUnlockedEvent>(options);
builder.RegisterMessageBroker<AchievementProgressChangedEvent>(options);
}
}
ProjectLifetimeScope registration:
builder.RegisterInstance(_achievementDatabase);
AchievementInstaller.Install(builder, options);
| Module | Relationship |
|--------|-------------|
| UnlockConditionModule | UnlockConditionConfig for composable unlock conditions |
| StatsModule | IStatsService for progress values, StatsDefinition for progressive tracking |
| WalletModule | IWalletService for currency reward application |
| SteamModule | ISteamAchievementService for platform sync |
| GameStateModule | IGameStateService.IsPlayable for evaluation gating |
| SaveModule | ISaveService for persistence |
| LogModule | ILogService for diagnostic logging (nullable) |
MockFactory.CreateAchievementService() — mock with configurable countsTestFixtures.CreateAchievementDefinition() — SO with all fields configurableTestFixtures.CreateAchievementDatabaseConfig(params AchievementDefinition[]) — database configPackages/com.punkfuncgames.achievement/Runtime/PunkFuncGames.Achievement/
Config/AchievementDatabaseConfig.cs
Event/AchievementEvents.cs
Installer/AchievementInstaller.cs
Model/AchievementDefinition.cs
Model/AchievementCurrencyReward.cs
Model/AchievementStatReward.cs
Service/IAchievementService.cs
Service/AchievementService.cs
Packages/com.punkfuncgames.achievement/Tests/EditMode/
AchievementDefinitionTests.cs
AchievementServiceTests.cs
development
WalletModule reference — currency management with BigDouble support, reactive properties, caps, lifetime stats, and persistence. Use when working with currencies, wallets, or financial systems.
development
UnlockConditionModule reference — composable unlock conditions using ScriptableObjects with AND/OR/NOT logic, stat/currency/upgrade/prestige/gamestate/boolean checks, reactive service layer with progress tracking. Use when implementing unlock systems, gating, or progression requirements.
development
UndoModule reference — command pattern with undo/redo stacks, command merging, and reactive state. Use when implementing undo/redo, undoable actions, or command patterns.
tools
Unity UI Toolkit reference — UXML documents, USS styling, MVVM pattern (ViewModel + Presenter), custom VisualElements, responsive layout, animations, performance guidelines, and complete Figma-to-UI-Toolkit property mapping. Use when building or modifying UI with UI Toolkit, creating UXML/USS files, writing ViewModels or Presenters, designing screens/panels/components, or converting Figma designs to UI Toolkit.