Complete gamification engine for .NET — XP, levels, achievements, quests, streaks, tiered leaderboards, virtual economy, and analytics in one NuGet package.
Every app wants engagement. Every team rebuilds the same XP system, leaderboard, and achievement logic from scratch. GameifyKit gives you a production-tested engine in 3 lines of setup.
- One package — XP, levels, achievements, quests, streaks, leaderboards, economy, analytics, anti-cheat
- 3 lines to start —
AddGameifyKit()with sensible defaults - Storage-agnostic — InMemory, SQL Server, or PostgreSQL out of the box
- Event-driven — React to level-ups, achievements, and tier changes in real-time
- Thread-safe — Built for concurrent workloads
- Fully tested — Every public method has a test
dotnet add package GameifyKitbuilder.Services.AddGameifyKit(options =>
{
options.UseInMemoryStore(); // or UseSqlServer() / UsePostgreSql()
options.ConfigureLeveling(lvl =>
{
lvl.Curve = LevelCurve.Exponential;
lvl.BaseXp = 100;
lvl.Multiplier = 1.5;
lvl.MaxLevel = 100;
});
});public class MyService
{
private readonly IGameEngine _game;
public MyService(IGameEngine game) => _game = game;
public async Task OnQuizCompleted(string userId, int score)
{
// Award XP (rules engine auto-checks limits & cooldowns)
var result = await _game.Xp.AddAsync(userId, score * 10, "quiz-complete");
// result.FinalXp = 1700, result.Level = 14, result.LeveledUp = true
// Check achievements
await _game.Achievements.IncrementAsync(userId, "quizzes_completed");
var unlocked = await _game.Achievements.CheckAsync(userId);
// Record streak
var streak = await _game.Streaks.RecordAsync(userId, "daily-login");
// streak.CurrentStreak = 8, streak.MilestoneReached = "Week Warrior"
}
}Three curve types for XP progression:
| Curve | Description |
|---|---|
| Linear | Same XP per level (e.g., 100 XP each) |
| Exponential | Each level needs Multiplierx more XP |
| Custom | Define exact thresholds per level |
options.ConfigureLeveling(lvl =>
{
lvl.Curve = LevelCurve.Exponential;
lvl.BaseXp = 100;
lvl.Multiplier = 1.5;
lvl.MaxLevel = 100;
});Built-in achievements + define your own with counters or custom conditions:
options.ConfigureAchievements(ach =>
{
ach.UseBuiltIn(BuiltInAchievements.FirstLogin);
ach.UseBuiltIn(BuiltInAchievements.Streak7);
ach.Define("quiz-master", a =>
{
a.Name = "Quiz Master";
a.Counter = "quizzes_completed";
a.Target = 50;
a.XpReward = 500;
a.Tier = AchievementTier.Gold;
});
ach.Define("night-owl", a =>
{
a.Name = "Night Owl";
a.Condition = ctx => ctx.LastActivityTime.Hour is >= 0 and < 5;
a.Secret = true; // Hidden until unlocked
});
});Multi-step quests with time limits and recurring support:
options.ConfigureQuests(q =>
{
q.Define("onboarding", quest =>
{
quest.Name = "Getting Started";
quest.Steps = new[]
{
new QuestStep("complete-profile", "Complete your profile", xpReward: 50),
new QuestStep("first-quiz", "Take your first quiz", xpReward: 100),
};
quest.CompletionBonus = 500;
quest.TimeLimit = TimeSpan.FromDays(7);
quest.AutoAssign = true;
});
});Daily/weekly streaks with grace periods and milestone rewards:
options.ConfigureStreaks(s =>
{
s.Define("daily-login", streak =>
{
streak.Period = StreakPeriod.Daily;
streak.GracePeriod = TimeSpan.FromHours(36);
streak.Milestones = new[]
{
new StreakMilestone(7, xpBonus: 150, badge: "Week Warrior"),
new StreakMilestone(30, xpBonus: 500, badge: "Monthly Legend"),
};
});
});Bronze to Diamond tiers with daily/weekly/monthly/all-time periods:
options.ConfigureLeaderboard(lb =>
{
lb.Periods = new[] { LeaderboardPeriod.Weekly, LeaderboardPeriod.AllTime };
lb.Tiers = new[]
{
new TierDefinition("bronze", "Bronze", maxPercentile: 0.50),
new TierDefinition("silver", "Silver", maxPercentile: 0.75),
new TierDefinition("gold", "Gold", maxPercentile: 0.90),
new TierDefinition("diamond", "Diamond", maxPercentile: 1.00),
};
lb.PromotionBonusXp = 200;
});Time-limited multipliers with stacking and max cap:
await _game.Boosts.ActivateAsync(userId, new XpBoost
{
Multiplier = 2.0,
Duration = TimeSpan.FromHours(48),
Reason = "weekend-bonus"
});
// XP awards automatically use active multipliers
var result = await _game.Xp.AddAsync(userId, 100, "quiz");
// result.Multiplier = 2.0, result.FinalXp = 200Currency earned from XP, reward shop with purchase limits:
options.ConfigureEconomy(e =>
{
e.CurrencyName = "coins";
e.XpToCurrencyRatio = 10; // Every 10 XP = 1 coin
e.DefineReward("extra-time", r =>
{
r.Name = "Extra Exam Time";
r.Cost = 100;
r.MaxPurchasesPerDay = 3;
});
});Track engagement metrics across your player base:
var insights = await _game.Analytics.GetInsightsAsync();
// insights.DailyActiveUsers, insights.AverageXpPerPlayer, etc.Daily XP caps, cooldowns, action limits, and suspicious activity alerts:
options.ConfigureRules(rules =>
{
rules.MaxDailyXp = 5000;
rules.Cooldown("quiz-complete", TimeSpan.FromMinutes(2));
rules.MaxActionsPerHour = 200;
});React to every state change in real-time:
options.OnEvent<LevelUpEvent>(async e =>
{
await SendNotification(e.UserId, $"Level {e.NewLevel}!");
});
options.OnEvent<AchievementUnlockedEvent>(async e =>
{
await SendNotification(e.UserId, $"Unlocked: {e.Achievement.Name}!");
});
options.OnEvent<TierChangeEvent>(async e =>
{
await SendNotification(e.UserId, $"Promoted to {e.NewTier.Name}!");
});Get a complete player state in a single call:
var profile = await _game.GetProfileAsync(userId);
// profile.TotalXp, profile.Level, profile.CurrentLevelProgress
// profile.Tier, profile.Rank
// profile.Achievements, profile.ActiveQuests, profile.ActiveStreaks
// profile.ActiveBoosts, profile.Wallet, profile.Stats| Provider | Use Case | Setup |
|---|---|---|
| InMemory | Testing, prototyping | options.UseInMemoryStore() |
| SQL Server | Production (MSSQL) | options.UseSqlServer(connectionString) |
| PostgreSQL | Production (Postgres) | options.UsePostgreSql(connectionString) |
Database stores auto-create tables (prefixed with GameifyKit_) on first use.
┌──────────────────────────┐
│ IGameEngine │
│ (Main Entry Point) │
└────────────┬─────────────┘
│
┌────────────────────────┼────────────────────────┐
│ │ │ │ │
┌────┴────┐ ┌────┴────┐ ┌────┴────┐ ┌────┴────┐ ┌─────┴─────┐
│XpEngine │ │Achieve- │ │ Quest │ │ Streak │ │Leaderboard│
│ │ │ment │ │ Engine │ │ Engine │ │ Engine │
└────┬────┘ │Engine │ └────┬────┘ └────┬────┘ └─────┬─────┘
│ └────┬────┘ │ │ │
│ │ │ │ │
┌────┴────┐ ┌────┴────┐ ┌───┴────┐ ┌────┴────┐ ┌─────┴─────┐
│ Boost │ │Economy │ │Analyt- │ │ Rule │ │ Event │
│ Engine │ │ Engine │ │ics │ │ Engine │ │ Bus │
└────┬────┘ └────┬────┘ └───┬────┘ └────┬────┘ └─────┬─────┘
│ │ │ │ │
└───────────┴──────────┴────────────┴─────────────┘
│
┌────────────┴─────────────┐
│ IGameStore │
│ (Storage Abstraction) │
└──────────────────────────┘
│ InMemory │ SQL Server │ PostgreSQL │
GameifyKit was extracted from the gamification system powering an enterprise education platform serving 1,500+ students. The XP curves, streak mechanics, and anti-cheat rules were all refined based on real student behavior data over 4+ years.
| Need | Use Instead |
|---|---|
| Full game engine | Unity, Godot |
| Social features | Your own social layer |
| Push notifications | Your notification service |
| UI components | Your frontend framework |
| Real-money transactions | Payment processing service |
GameifyKit is the engine. You build the experience.
| Option | Type | Default | Description |
|---|---|---|---|
Leveling.Curve |
LevelCurve |
Exponential |
XP curve type |
Leveling.BaseXp |
int |
100 |
Base XP for first level |
Leveling.Multiplier |
double |
1.5 |
Exponential multiplier |
Leveling.MaxLevel |
int |
100 |
Maximum level |
Boosts.MaxStackableBoosts |
int |
3 |
Max simultaneous boosts |
Boosts.MaxMultiplier |
double |
5.0 |
Max combined multiplier |
Economy.XpToCurrencyRatio |
int |
10 |
XP per currency unit |
Rules.MaxDailyXp |
int |
5000 |
Daily XP cap |
Rules.MaxActionsPerHour |
int |
200 |
Hourly action limit |
Leaderboard.PromotionBonusXp |
int |
200 |
XP bonus on tier promotion |
The included sample API demonstrates real usage:
POST /api/game/{userId}/xp — Add XP
GET /api/game/{userId}/profile — Full player profile
GET /api/game/{userId}/achievements — Player achievements
POST /api/game/{userId}/quests/progress — Progress a quest
GET /api/game/{userId}/quests — Active quests
GET /api/game/leaderboard/{period} — Leaderboard
GET /api/game/{userId}/standing — Player standing
POST /api/game/{userId}/boost — Activate boost
GET /api/game/{userId}/wallet — Wallet balance
POST /api/game/{userId}/purchase — Purchase reward
GET /api/game/analytics — Engagement insights
# Clone the repository
git clone https://github.com/mcandiri/gamifykit.git
cd gamifykit
# Restore dependencies
dotnet restore
# Build the solution
dotnet build
# Run all tests (161 tests)
dotnet test
# Run the sample API
dotnet run --project samples/GameifyKit.SampleApi
# Open http://localhost:5000/swagger- Redis-backed leaderboard for high-scale scenarios
- Webhook notifications on events
- Admin dashboard (Blazor)
- Team/guild support
- A/B testing for gamification rules
- Seasonal events system
Contributions are welcome! Please open an issue first to discuss what you would like to change.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request