Static helper that lists stat and achievement identifier constants for the game and exposes thin wrappers to increment stats and unlock achievements via Sandbox Services Stats and Achievements.
using Sandbox.Services;
namespace BrickJam;
/// <summary>
/// Central catalogue of the s&box <see cref="Sandbox.Services"/> stat + achievement identifiers this game
/// reports, plus thin wrappers over <c>Stats</c>/<c>Achievements</c>.
///
/// Stats and achievements are tied to the LOCAL player's account, so these must run on the OWNING client -
/// host-side gameplay routes through <see cref="Player.TrackStat"/>/<see cref="Player.TrackAchievement"/>
/// (which are <c>[Rpc.Owner]</c>), and owner-side code (e.g. <see cref="Player.Kill"/>) can call here directly.
///
/// IMPORTANT: stats, achievements and leaderboards only register against a PUBLISHED game package - they must
/// be defined on the game's sbox.game dashboard to persist, unlock, and appear on leaderboards. In local play
/// the Services calls safely no-op (the package resolves to null), so this is harmless during development.
///
/// Leaderboards are configured on the dashboard FROM these stats (e.g. a "money_earned" leaderboard), so just
/// reporting the stats below feeds them - no extra code needed unless we add an in-game leaderboard panel.
/// </summary>
public static class GameStats
{
// --- Stats (cumulative; each can back a dashboard leaderboard of the same name) ---
public const string MoneyEarned = "money_earned";
public const string LootCollected = "loot_collected";
public const string LootSold = "loot_sold";
public const string LocksPicked = "locks_picked";
public const string LevelsCompleted = "levels_completed";
public const string Deaths = "deaths";
public const string Escapes = "escapes";
public const string SavesLoaded = "saves_loaded"; // backs the stat-mode file_explorer achievement
public const string LevelsEscapedUnique = "levels_escaped_unique"; // backs the stat-mode grand_tour achievement
// --- Achievements (manual unlocks; the identifier must exist on the dashboard) ---
public const string AchFirstSale = "first_sale";
public const string AchEscape = "escape";
// Newer batch. STAT-mode achievements (file_explorer/the_one_percent/grand_tour) auto-unlock on the
// dashboard from their backing stat crossing a threshold - code only reports the stat. The rest are
// one-shot EVENT unlocks fired from gameplay via Player.TrackAchievement. All idents must be defined on
// the sbox.game dashboard to actually persist/unlock for a player.
public const string AchFileExplorer = "file_explorer"; // STAT saves_loaded >= 50
public const string AchThePercent = "the_one_percent"; // STAT money_earned >= 10,000
public const string AchGrandTour = "grand_tour"; // STAT levels_escaped_unique >= 3
public const string AchSlippedOnSoap = "slipped_on_soap"; // die in the Bathrooms within 30s of entering
public const string AchLeftForDead = "left_for_dead"; // escape as the sole survivor
public const string AchHoardersParadise = "hoarders_paradise";// extract with a full inventory
public const string AchFullyLoaded = "fully_loaded"; // own every shop upgrade
public const string AchOutsmarted = "outsmarted"; // lose a monster that was chasing you
public const string AchGoodBoy = "good_boy"; // summon Doob for the first time
public const string AchBodyguard = "bodyguard"; // Doob takes a monster hit for you
public const string AchManslaughterByProxy = "manslaughter_by_proxy"; // a nearby teammate dies while you (with Doob) live
public static void Increment( string name, double amount = 1 ) => Stats.Increment( name, amount );
public static void Unlock( string ident ) => Achievements.Unlock( ident );
}