com.stratkit.user-activity-tracker¶
Tracks per-game-round user activity for use by triggers (e.g. rate-us popup).
What it tracks¶
Each field is scoped to the current game round (GameId), except AccountAgeDay which is account-wide.
| Field | Description |
|---|---|
AccountAgeDay |
Days since user registration |
SessionCount |
Number of sessions started in this round |
SessionLength |
Cumulative play time in this round across all sessions (seconds) |
DailyLoginStreak |
Consecutive in-game-days the player logged into this round |
PointsTrend |
Decreasing / Stable / Increasing derived from per-day ranking points history |
DailyHistory |
Ring buffer of per-day ranking points snapshots |
Persisted to PlayerPrefs keyed by userId (one entry per account, not per round). Joining a different game round resets the round-scoped counters and overwrites the same key.
Data is local-only, not cross-platform.
How it works¶
Three systems run in the persistent world:
UserActivityPersistenceSystem— loads the log on user-ready; writes back whenUserActivityLogDirtytag is present.UserActivityUpdateSystem— runs everySessionUpdateInterval. One pass handles day rollover (streak, ranking snapshot, trend recompute), session expiry, session-length extension, and dirty-tag emission.UserInactivityStateUpdateSystem— runs every frame; stampsLastInteractionTimestampon any input edge and additionally stampsLastUserActionTimestampwhen aServerCommandRequestexists.
Ranking points come from CurrentDayPlayerRankingPointsComponent (set per player by RankingPointsPlayerResolverSystem in com.stratkit.newspaper-state-loader).
Inactivity tracking (busy / idle gate)¶
In addition to the day-level log, the package exposes a UserInactivityStateComponent singleton with two timestamps:
LastInteractionTimestamp— last UI click / tap / key (legacyhup.lastClick).LastUserActionTimestamp— last in-game command issued (legacylastUserActionTime).
UserInactivityStateUpdateSystem writes both timestamps automatically — no host wiring needed. PositionActionComponent (from com.stratkit.user-input-actions) bumps LastInteractionTimestamp; ServerCommandRequest (from com.stratkit.game-state-loader) additionally bumps LastUserActionTimestamp.
Consumers query idle state via:
which returns the matching InactivityKind (or None when active) once either threshold has elapsed (NoInteractionTimeout = 30s and, in-game only, NoActionTimeout = 15s). Mirrors legacy ReviewTrigger.onUserInactive / onUserInactiveNoAction.
Enable / disable¶
UserActivityTrackerUtils.Disable() stops all ticking and IO; Enable() resumes. The state is persisted to PlayerPrefs and re-applied at module setup, so a disable survives app restarts (e.g. once rate-us no longer needs the data after the player has rated).
Consumers¶
Read UserActivityLogComponent from the persistent world. The PointsTrend is the most commonly gated-on field — it's set to Unknown when there's no in-game data yet (uber / lobby), Stable when only one day of data exists.
Setup¶
Create a UserActivityTrackerModule asset and add it to the persistent world module list. Config values are edited directly on the module asset (UserActivityTrackerConfig is an embedded [Serializable] struct — no separate config asset).