cjmellor/level-up/level-up-development

Claude Code and agent skill by cjmellor/level-up

Trust tier 3
  • community
Source check pending

Checking that the SKILL.md file is still in the repository.

Build and work with cjmellor/level-up features, including XP, levels, tiers, achievements, streaks, multipliers, challenges, leaderboards, leagues, and auditing.

Install

npx vskill@latest install cjmellor/level-up/level-up-development

SKILL.md

When to use this skill

Use this skill when working with gamification features — adding experience points, levels, tiers, achievements, streaks, multipliers, leaderboards, leagues, or auditing — using cjmellor/level-up.

Core Concepts

  • XP and Levels — Users earn experience points (XP) and automatically progress through a defined level structure.
  • Tiers — Named status brackets (e.g. Bronze, Silver, Gold) based on XP thresholds, independent of numeric levels.
  • Achievements — Unlockable rewards, optionally with progress tracking, optionally gated by tier.
  • Streaks — Track consecutive daily activities with freeze support.
  • Multipliers — Database-backed point modifiers with scoping, scheduling, and configurable stacking strategies.
  • Leaderboard — Rank users by any metric (XP by default) with competition-style rank numbers, optionally scoped to a tier or a time period (day/week/month/custom).
  • Leagues — A competitive cycle on one periodic Board: active users are grouped into small Cohorts within a Division each period and ranked within their Cohort. A Division is competition history, NOT a Tier (which is XP status) — a user holds both independently.
  • Auditing — Automatic history of all XP changes, level-ups, and tier changes.

Setup

Install
bash
composer require cjmellor/level-up
php artisan vendor:publish --tag="level-up-migrations"
php artisan migrate
php artisan vendor:publish --tag="level-up-config"
Add Traits to the User Model

Add only the traits you need:

php
use LevelUp\Experience\Concerns\GiveExperience;
use LevelUp\Experience\Concerns\HasAchievements;
use LevelUp\Experience\Concerns\HasChallenges;
use LevelUp\Experience\Concerns\HasLeagues;
use LevelUp\Experience\Concerns\HasStreaks;
use LevelUp\Experience\Concerns\HasTiers;
class User extends Authenticatable
{
use GiveExperience; // Required — XP and levels
use HasAchievements; // Optional — achievements
use HasStreaks; // Optional — streaks
use HasTiers; // Optional — tiers
use HasChallenges; // Optional — challenges
use HasLeagues; // Optional — leagues (divisions/cohorts)
}

GiveExperience is the foundation. The others are opt-in.

Levels

Define Levels
php
use LevelUp\Experience\Models\Level;
Level::add(
['level' => 1, 'next_level_experience' => null],
['level' => 2, 'next_level_experience' => 100],
['level' => 3, 'next_level_experience' => 250],
['level' => 4, 'next_level_experience' => 500],
['level' => 5, 'next_level_experience' => 1000],
);

Level 1 must have next_level_experience set to null — it is the default starting point. Users level up automatically when their XP reaches the threshold. Throws LevelExistsException if a level number already exists.

Level Queries
php
$user->getLevel(); // Current level number (int), 0 if no experience
$user->getPoints(); // Current XP total (int), 0 if no experience
$user->nextLevelAt(); // XP remaining until next level (int)
$user->nextLevelAt(checkAgainst: 5); // XP remaining until level 5
$user->nextLevelAt(showAsPercentage: true); // Progress as 0-100 percentage
Manual Level Up
php
$user->levelUp(to: 5); // Jump to level 5

Throws InvalidArgumentException if the level does not exist. Fires UserLevelledUp for each intermediate level gained. Respects the level cap.

Level Cap

Configured in config/level-up.php:

php
'level_cap' => [
'enabled' => env('LEVEL_CAP_ENABLED', true),
'level' => env('LEVEL_CAP', 100),
'points_continue' => env('LEVEL_CAP_POINTS_CONTINUE', true),
],

When the cap is reached, the user stops levelling. If points_continue is true, XP still accumulates. If false, XP stops accumulating too.

Experience Points (XP)

Add Points
php
$user->addPoints(50);
$user->addPoints(50, reason: 'Completed tutorial');
$user->addPoints(50, multiplier: 2);
$user->addPoints(50, type: AuditType::Add->value, reason: 'Bonus');

Creates an experience record if none exists, otherwise increments. Automatically levels up if the threshold is crossed. Points past the highest level's next_level_experience cap the user at the top level (no exception).

Deduct Points
php
$user->deductPoints(30);
$user->deductPoints(30, reason: 'Penalty');

Throws Exception if the user has no experience record.

Set Points
php
$user->setPoints(500);

Directly overwrites the XP total, then recalculates level and tier from the new total (firing UserLevelledUp / UserTierUpdated as needed). Throws Exception if the user has no experience record. Writes no audit record — it is an administrative override, invisible to periodic leaderboards.

Get Points
php
$user->getPoints(); // int, returns 0 if no experience record

Multipliers

Multipliers are database-backed records that modify point calculations. They can be scoped to specific users or tiers, scheduled with time windows, and configured to stack using different strategies.

Create Multipliers
php
use LevelUp\Experience\Models\Multiplier;
Multiplier::create([
'name' => 'Weekend Bonus',
'multiplier' => 2.0,
'is_active' => true,
'starts_at' => now()->startOfWeekend(),
'expires_at' => now()->endOfWeekend(),
]);

Active multipliers are automatically applied when addPoints() is called. The multiplier value must be at least 0.01. If both starts_at and expires_at are set, starts_at must be before expires_at.

Scope Multipliers

Multipliers with no scopes apply to all users. Use the typed scopeToUser / scopeToTier methods to restrict:

php
$multiplier->scopeToUser($user); // Specific user only
$multiplier->scopeToTier($goldTier); // Gold tier users only
$multiplier->scopeToUser($user)->scopeToTier($tier); // Both — chains via fluent return
// Variadic — attach multiple of the same type in one call
$multiplier->scopeToUser($alice, $bob, $carol);
$multiplier->scopeToTier($silver, $gold, $platinum);
// Reverse the scope
$multiplier->unscopeFromUser($user);
$multiplier->unscopeFromTier($goldTier);
// Check whether a multiplier has any scopes attached
$multiplier->isGlobal(); // true when no users or tiers attached

scopeToUser and scopeToTier are idempotent (they use syncWithoutDetaching internally) — calling them twice with the same model does not create duplicates.

Inline Multiplier
php
$user->addPoints(amount: 10, multiplier: 3); // 30 points

Inline multipliers stack with DB multipliers according to the configured strategy.

Stacking Strategies

Configure in config/level-up.php:

php
'multiplier' => [
'enabled' => env('MULTIPLIER_ENABLED', true),
'stack_strategy' => env('MULTIPLIER_STACK', 'compound'),
// 'compound' — multipliers multiply each other: 2 × 5 = 10x
// 'additive' — multipliers sum: 2 + 5 = 7x
// 'highest' — only the largest applies: max(2, 5) = 5x
],
Query Multipliers
php
Multiplier::active()->get(); // Currently active
Multiplier::active()->forUser($user)->get(); // Active for a specific user
Multiplier::scheduled()->get(); // Future (starts_at > now)
Multiplier::expired()->get(); // Past (expires_at < now)
MultiplierApplied Event

Fires when multipliers modify a point calculation. Properties: Model $user, Collection $multipliers, int $originalAmount, int $finalAmount, string $strategy.

Tiers

Define Tiers
php
use LevelUp\Experience\Models\Tier;
Tier::add(
['name' => 'Bronze', 'experience' => 0],
['name' => 'Silver', 'experience' => 500],
['name' => 'Gold', 'experience' => 2000],
['name' => 'Platinum', 'experience' => 5000, 'metadata' => ['color' => '#E5E4E2', 'icon' => 'crown']],
);

Tier names and experience values must be unique. Throws TierExistsException on duplicates. The metadata column is a flexible JSON field for any extra data (colours, icons, descriptions). The entire add() call is wrapped in a database transaction — if any tier fails, none are created.

Automatic Tier Promotion

Tiers update automatically when XP changes. When addPoints() causes the user to cross a tier threshold, experience.tier_id is updated and a UserTierUpdated event fires with TierDirection::Promoted.

Query Tiers
php
$user->getTier(); // Current Tier model or null
$user->getNextTier(); // Next tier above current (Tier or null)
$user->tierProgress(); // Percentage 0-100 through current bracket
$user->nextTierAt(); // XP remaining until next tier
$user->isAtTier('Gold'); // Exact match (bool)
$user->isAtOrAboveTier('Silver'); // At or above (bool)

getTier() returns null if the user has no experience record or tiers are disabled.

Demotion

By default, tiers use a high-water mark — once earned, they persist even if points decrease. Enable demotion to allow tier drops:

TIER_DEMOTION=true

When enabled, deductPoints() checks if the user should drop and fires UserTierUpdated with TierDirection::Demoted. The newTier property is nullable — it will be null if the user drops below all tier thresholds.

Tier-Scoped Multipliers

Create a multiplier and scope it to a tier so it only applies to users at that tier:

php
$multiplier = Multiplier::create([
'name' => 'Gold Bonus',
'multiplier' => 2.0,
'is_active' => true,
]);
$goldTier = Tier::where('name', 'Gold')->first();
$multiplier->scopeToTier($goldTier);

When a Gold-tier user calls addPoints(), this multiplier is automatically included.

Tier-Gated Achievements

Restrict achievements so only users at a certain tier can earn them:

php
$goldTier = Tier::where('name', 'Gold')->first();
Achievement::create([
'name' => 'Golden Streak',
'tier_id' => $goldTier->id,
]);

Attempting to grant to a user below Gold throws TierRequirementNotMet.

Tier-Scaled Streak Freezes

Higher tiers get longer freeze durations:

php
// config/level-up.php
'tiers' => [
'streak_freeze_days' => [
'Bronze' => 1,
'Silver' => 2,
'Gold' => 3,
'Platinum' => 7,
],
],

Falls back to the global freeze_duration if the tier is not listed or tiers are disabled.

Tier-Scoped Leaderboards
php
use LevelUp\Experience\Facades\Leaderboard;
Leaderboard::forTier('Gold')->generate();
Leaderboard::forTier($tierModel)->generate();
Tier Config
php
'tiers' => [
'enabled' => env('TIERS_ENABLED', true),
'demotion' => env('TIER_DEMOTION', false),
'streak_freeze_days' => [],
],

Achievements

Create Achievements
php
use LevelUp\Experience\Models\Achievement;
Achievement::create([
'name' => 'First Login',
'is_secret' => false,
'description' => 'Log in for the first time',
'image' => 'storage/app/achievements/first-login.png',
]);
// Secret achievement (hidden until earned)
Achievement::create([
'name' => 'Hidden Gem',
'is_secret' => true,
]);
// Tier-gated achievement
Achievement::create([
'name' => 'Gold Member Badge',
'tier_id' => $goldTier->id,
]);
Grant Achievement
php
$user->grantAchievement($achievement);
// With progress (0-100)
$user->grantAchievement($achievement, progress: 50);

Throws Exception if progress exceeds 100, or if the user already has the achievement. Throws TierRequirementNotMet if tier-gated and user does not meet the tier requirement. AchievementAwarded event fires only when progress is null or 100.

Revoke Achievement
php
$user->revokeAchievement($achievement);

Throws Exception if the user does not have the achievement.

Achievement Progress

This is the start of the file. Read the full SKILL.md on GitHub.

Security

  • Security scanPassed, 95 of 100Pattern checks on the skill's files.
  • Model reviewPassed

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

Repository stars
670
Repository forks
55
7-day trend score
33

Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/cjmellor/level-up/level-up-development/badge)](https://verified-skill.com/skills/cjmellor/level-up/level-up-development)

Something wrong with this skill or its page? Tell us.