.claude/skills/stats-module/SKILL.md
StatsModule reference — stat tracking with BigDouble values, event publishing, stat caps, source tracking, batched persistence, and initial value tracking. Use when working with player stats, tracking metrics, or achievement progress.
npx skillsauth add punkfuncgames/tetris-clone stats-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.stats | Define: PUNKFUNC_STATS
Location: Packages/com.punkfuncgames.stats/Runtime/PunkFuncGames.Stats/
Namespace: PunkFuncGames.Stats
Registration:
RegisterStat(StatsDefinition, BigDouble initialValue = default) — registers and applies saved data if availableRegisterStats(IEnumerable<StatsDefinition>)UnregisterStat(StatsDefinition) — removes stat, caps, and initial valuesOperations:
Set(StatsDefinition/string, BigDouble value, StatChangeSource source = Manual) — sets value (capped)Add(StatsDefinition/string, BigDouble amount, StatChangeSource source = Gameplay) — adds amount (capped)bool Consume(StatsDefinition/string, BigDouble amount, StatChangeSource source = Gameplay, string context = "") — returns false + publishes StatConsumeFailedEvent if insufficientQueries:
BigDouble GetValue(StatsDefinition/string) — returns BigDouble.Zero for unregisteredbool HasEnough(StatsDefinition/string, BigDouble amount) — convenience checkStatsDefinition GetStatDef(string) — lookup by DisplayNameKeyIEnumerable<StatsDefinition> GetAllStats()int RegisteredStatCountbool IsInitializedCaps:
SetCap(StatsDefinition/string, BigDouble cap) — enforces max value, clamps if current > capRemoveCap(StatsDefinition/string) — sets cap to BigDouble.PositiveInfinityBigDouble GetCap(StatsDefinition/string) — returns BigDouble.PositiveInfinity if no capbool IsAtCap(StatsDefinition/string) — true when value >= cap (and cap is finite)Reset:
ResetStat(StatsDefinition) — resets to initial value (from RegisterStat)ResetAllStats() — resets all to initial valuesResetToZero(StatsDefinition) — explicit zero resetResetAllToZero() — all stats to zeroReset() — delegates to ResetAllStats() (IResettable)All events are readonly struct in PunkFuncGames.GameTemplate.Runtime.StatsModule.Event:
| Event | Fields | Published When |
|-------|--------|---------------|
| StatChangedEvent | Stat, NewValue, PreviousValue, Delta, Source | Set/Add/Consume changes value |
| StatResetEvent | Stat, PreviousValue, ResetToValue | ResetStat/ResetAll/ResetToZero |
| StatConsumeFailedEvent | Stat, AttemptedAmount, AvailableAmount, Context | Consume fails (insufficient) |
| StatCapChangedEvent | Stat, NewCap, PreviousCap | SetCap/RemoveCap |
Unknown, Manual, Gameplay, Achievement, Prestige, Cheat, SaveLoad, OfflineProgress
Same identity-object pattern as CurrencyDefinition.
StatsDefinition (ScriptableObject): Thin wrapper with public StatsDefinitionData data;
Access fields via definition.data.fieldName.
StatsDefinitionData ([Serializable] public struct, camelCase fields):
string displayNameKey — unique ID (auto-set from asset name)Sprite icon, Color colorbool showInUI, int uiSortOrderbool hasCap, SerializableBigDouble initialCap — definition-level cap applied on RegisterStatImplements: IStatsService, IAsyncStartable, ITickable, IDisposable
Dependencies: ISaveService, ILogService, IPublisher<StatChangedEvent>, IPublisher<StatResetEvent>, IPublisher<StatConsumeFailedEvent>, IPublisher<StatCapChangedEvent>
"StatsData", version 1RegisterStat() is calledTick() flushes every 5sStatsInstaller.Install(builder, options);
// Registers: StatsService as IStatsService (EntryPoint for IAsyncStartable/ITickable)
// Brokers: StatChangedEvent, StatResetEvent, StatConsumeFailedEvent, StatCapChangedEvent
// Register stats (usually in a bootstrap phase or game scope)
_statsService.RegisterStat(totalKillsStat);
_statsService.RegisterStat(playTimeStat, new BigDouble(0));
// Track gameplay with source
_statsService.Add("TotalKills", BigDouble.One, StatChangeSource.Gameplay);
_statsService.Set("PlayTime", new BigDouble(totalSeconds), StatChangeSource.Manual);
// Spend-like operations
if (_statsService.Consume("Energy", new BigDouble(10), StatChangeSource.Gameplay, "spell_cast"))
{
// success
}
// Query
BigDouble kills = _statsService.GetValue("TotalKills");
bool canCast = _statsService.HasEnough("Energy", new BigDouble(10));
// Caps
_statsService.SetCap(energyStat, new BigDouble(100));
bool full = _statsService.IsAtCap(energyStat);
// Subscribe to events
_subscriber.Subscribe(evt =>
{
Debug.Log($"{evt.Stat.data.displayNameKey} changed by {evt.Delta} ({evt.Source})");
});
MockFactory.CreateStatsService(Dictionary<string, BigDouble>) — functional mock with Get/Set/Add/Consume/HasEnoughTestFixtures.CreateStatsDefinition(displayNameKey, hasCap, initialCap, showInUI, sortOrder) — creates ScriptableObject with data struct initializeddevelopment
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.