- How do I install cjmellor/level-up in a Laravel application?
- Install it with Composer (composer require cjmellor/level-up), then publish and run the package migrations and review the config file before migrating. Add the package traits to your User model so it can accumulate experience, levels, achievements, streaks, and challenges. Because the traits define methods such as experience(), challenges(), and streaks(), check that your model does not already declare conflicting methods, since v3 removed the trait method aliasing helpers. Run the migrations on a copy of production data first if you already have gamification tables.
- Which database versions does the Level-Up leaderboard require?
- Rank numbers are computed with SQL window functions, so you need MySQL 8 or newer, or SQLite 3.25 or newer. MySQL 5.7 is explicitly unsupported, so any RDS or Aurora estate still on 5.7 must be upgraded before the leaderboard feature is usable. The experience points, levels, and achievements core can still run without window functions, so upgrading the database can be a phased rollout rather than a hard blocker for the whole package.
- Is cjmellor/level-up v3 a breaking change from v2?
- Yes, v3.0.0 is a hard major release with schema, code contract, return type, and behavioural breaks. The polymorphic multiplier_scopes table is replaced by typed multiplier_user and multiplier_tier pivots, the MultiplierScope model and several config keys were removed, and Multiplier::scopeTo() plus the UserForeignKey helper are gone. Leaderboard::generate() now returns LeaderboardEntry objects instead of User collections, which will break Blade views, API resources, and JSON contracts at runtime. Review the upgrade notes and audit any host code that reads the old config keys or joins the old table.
- Can I add a custom leaderboard metric or a new board in Level-Up?
- Yes. Leaderboards are declared as named boards in config and scored through RankingMetric contracts, so most product requests such as top ten by weekly XP within a guild can be handled with configuration plus a small custom metric class. This extension point means you generally do not need to fork the package. Implement the metric contract, register the board in config, and let the package handle ranking and snapshot persistence.
- Do I need a scheduler for Level-Up leaderboards and leagues?
- Yes. v3 adds snapshot commands such as level-up:snapshot-boards and league-related commands that periodically persist derived standings, so the package expects a schedulable process in your application. Treat it as a stateful subsystem with a ledger, derived data lifecycle, and scheduled jobs rather than a stateless utility library. Without a working scheduler your boards can still be generated on demand, but stored snapshots and league standings will go stale.
- How expensive are Level-Up leaderboard queries on a large users table?
- Rank computation runs window functions over the users and experience audit joins, per metric, per period, per restricted set, and per board, so cost scales with user count rather than board size. Methods like around() and rankOf() also imply per-user rank calculation, which can be costly without the right indexes on the experience_audits ledger. Rely on scheduled snapshots for frequently read boards and index the columns used by your metrics before exposing leaderboards to high traffic.
- Is the v3 migration safe to run on a large production database?
- Treat it with caution. A backfill migration runs automatically during php artisan migrate, and there is no documented batching, dry-run, or resumability, so a large multiplier_scopes table becomes an unbounded production migration. The new pivot tables also lack a clear down() story, making rollback awkward once data has been reshaped. Rehearse the migration against a production-sized copy and plan a maintenance window or manual batching strategy.
- Why did achievement or XP rewards double-count after upgrading to Level-Up v3?
- Several silent behavioural changes landed in v3: setPoints() now fires UserLevelledUp and UserTierUpdated, auditing defaults to true, and excess points cap at the top level instead of throwing. If your own listeners also award points or levels in response to those events, rewards can be applied twice, and misconfigured level thresholds are now masked rather than surfaced as errors. All package events implement ShouldDispatchAfterCommit, which is safer for mail and HTTP calls but changes when your listeners observe state.
- How should I test gamification features built with Level-Up?
- Use RefreshDatabase rather than wrapping tests in an open transaction, because the package events implement ShouldDispatchAfterCommit and will not fire until the transaction commits. Run your test suite against SQLite 3.25+ or MySQL 8+ so window-function ranking behaves the same as production. Assert on the experience audit ledger, level and tier records, and dispatched events, and fake the scheduler where snapshot commands would otherwise write derived rows.
- Is Level-Up a good fit for multi-tenant apps or non-User actors?
- It fits an existing Laravel monolith or modular monolith cleanly, since it is Laravel-native with Eloquent models, migrations, config, Artisan commands, and events. It is a poor fit where you cannot expose a schedulable process, such as strictly per-tenant queues, or where the User model is not the canonical actor earning progress. In those cases consider a lighter trait or event-based approach, or wrap the package behind your own models so tenant scoping and actor mapping stay under your control.