Server Admin

Scuffed Professions

Requirements, staff and recovery commands, permission nodes, configuration keys and defaults, boosts and store setup, content packs, backups, integrations, placeholders and API.

Gameplay GuideView the players side of Scuffed Professions

Last updated

Install, staff-command, permission, configuration, storage and recovery reference for server operators. For how the professions play (XP, skill trees, capstones, boosts and rewards) see the Scuffed Professions gameplay guide.

  • Plugin version: 0.25.80-pre.8 (plugin name ScuffedProfessions)

Requirements

PluginVersionType
Hytale server≥ 0.7.0-pre.0 and < 0.8.0Required
EndlessLevelingCore≥ 12.6.1Required
LuckPerms≥ 5.5.0Required
Farming (Hytale)anyOptional
FarmingPlusanyOptional
AnglersAlmanacanyOptional
ScuffedProtectionanyOptional
ScuffedNPCsanyOptional
Perfect DodgesanyOptional
EndlessForgedanyOptional
EndlessMarriageanyOptional
EndlessGuildsanyOptional
EndlessDurabilityanyOptional
BetterLootBoxanyOptional
EndlessRiftsanyOptional
EndlessEliteMobsanyOptional
EndlessFatesanyOptional

The plugin refuses to load without LuckPerms. It ships its own asset pack (blocks, items, models, UI pages and language files) inside the jar.

Tamework (Alec's Animal Husbandry), the Condensed Crops pack, PlaceholderAPI and an economy plugin are detected at runtime and are not in the manifest. Without them the matching features are simply unavailable (see Integrations).

First boot writes every default file under mods/ScuffedProfessions/. Existing files are never overwritten by a restart, so hand edits survive.


Admin & Staff Commands

All commands live under /professions (alias /prof). The command tree is opened to normal players so the player pages work, and every admin command checks in code for operator status or the scuffedprofessions.admin permission (see Permissions). From the console the admin commands are allowed and each use writes an [SP][AUDIT] line to the log.

General

CommandDescription
/professions adminOpen the Admin View page (player only)
/professions reloadReload every configuration table, packs and language caches. Replies with one short result; a malformed JSON file refuses the reload before anything applies
/professions debugcurvePrint the live XP curve (base, scale, cap, post-cap step), sample level costs and the curve self-check
/professions admin glintChest glint counters (writes per second, total, drops, lookups, lookup time)
/professions admin metrics [skill]Actions per hour, XP per hour and players per profession
/professions admin announce <text>Send one line to this server and the rest of the network

Player XP and progression

CommandDescription
/professions admin xp <player> <skill> <get|set|add|reset> [amount]Read or edit profession XP. Adding XP can pay level rewards, setting XP does not replay level-up effects
/professions admin skill <skill> <key> <value>Edit a live per-profession setting. Keys: enabled, xpmultiplier, fortune, rarefinds, statrows, durability, gates (inherit clears the override)
/professions admin perk <player> <profession> <optionId>Restore one valid tree choice, obeying the current level and pick limits
/professions admin claims reset <player> [skill]Clear tree claims for a player (every profession when the skill is left out). Run it twice within 10 seconds to confirm. Charges and grants no reset credits
/professions admin transcend <player> <skill> <set|clear>Set or clear the Transcended flag. clear needs the same 10 second double confirmation. Works on offline players
/professions admin resets balance <player> <profession>Show a player's reset credit balance
/professions admin resets give <player|all> <profession> <count> [--txn <receipt>]Grant tree reset credits. Repeat a partial or uncertain grant with the same receipt and amount; saved grants are not paid twice. all covers currently known players, offline profiles included
/professions admin diagnose <player> <profession>Levels, choices, pending deliveries and server-local recovery state
/professions admin reconcile <player> <profession>Retry already-owed work for an online player and refresh passives and unlocks. Does not replay ambiguous command rewards or refund money
/professions admin index rebuildRescan stored profiles for the player name index
/professions admin leaderboard rebuildRescan storage and rebuild the leaderboard ranking

Capstones

CommandDescription
/professions admin capstone <player> <skill> <grant|revoke|reissue|info>Grant, revoke, reissue or inspect a numbered capstone. revoke and reissue need the command repeated within 10 seconds
/professions admin capstones <skill>List who holds each number of a profession's capstone
/professions admin capstonehistory <profession> <number> [--page <n>]Recorded changes to one numbered capstone on this server (6 entries per page)
/professions admin capstonerepair <profession> <number> <recipient|revoke> "<reason>"Preview a reassignment or revocation. Reason is 1 to 500 characters
/professions admin capstoneconfirm <token>Apply your unchanged preview within 60 seconds

Boosts

CommandDescription
/professions admin boost listRunning boosts and the retained purchase ledger
/professions admin boost start <skill|all> <multiplier> <minutes> [by <name>] [--txn <id>] [--label <text>]Start a server-wide boost. --label takes the rest of the line, so put it last
/professions admin boost grant <template> <player> [<profession>] [--txn <id>]Start a boost bought from the store. This is what a store package runs
/professions admin boost stop <id|profession|all>Stop a purchase by id, every boost on a profession, or all. Later totals are recalculated; no money is refunded
/professions admin boost ordersUnresolved in-game payment intents
/professions admin boost resolveorder <order> <paid|not-paid> "<reason>"Record a decision after checking the economy ledger. It never charges or refunds money

The same four commands list, start, stop and grant also work as /professions boost <subcommand>, from the console too.

Backups, recovery and balance tools

CommandDescription
/professions admin backup nowCreate and verify a manual checkpoint
/professions admin backup listLatest ten usable checkpoints
/professions admin backup info <set|latest>Verify checksums and show counts and scope
/professions admin backup restore <set> <player|all> <profession|all> <fields> "<reason>" [--network-offline true]Preview a selective restore. fields is xp, tree, transcend, resets, a comma list, or all
/professions admin backup confirm <token>Apply your own preview within 120 seconds
/professions admin backup releasehold <player> "<reason>" [--network-offline true]Release a recovered missing profile after reviewing receipts and custody
/professions admin vaporisation history <player UUID|all>Last 20 A/S-tier Vaporiser destructions (retained 30 days or 5,000 records)
/professions admin vaporisation inspect <id> · preview <id>Show a record and what a restore would repay
/professions admin vaporisation restore <id>Restore a completed record. The original owner must be online here, have room in their main inventory, and hold the repayment in the lowest-tier core
/professions admin evidence [--profession <skill>] [--days <n>]XP-per-minute evidence report and balance suggestions; also writes reports/xp-evidence.txt and .csv
/professions admin evidence reset [--profession <skill>]Start the XP evidence log fresh. Run it twice within 10 seconds
/professions admin resetandcompensatePreview an XP reduction for XP earned under looser settings (see XP reset campaign)
/professions admin resetandcompensate confirm <token>Apply your preview within 120 seconds

Player-run staff commands

These three run in game only (they need a player sender) and check for admin access:

CommandDescription
/professions artifact <list|inspect|recover|revoke|grant|resetritual> <id>Relic and revival incense ledger. <id> is an artifact UUID, held for the item in your hand, - for list, a kind for grant (Gaia, Drum, Lantern, Orrery, Seeds, Provisions, Ritual) or a player UUID for resetritual (clears the 30 minute incense crafting cooldown). Recover and revoke change the generation so older copies stop working
/professions rewardclaims <list|retry|settle|recover> <online player UUID> <reward id or ->Inspect or resolve a saved tier reward delivery. retry can duplicate a key if the first delivery succeeded, so check BetterLootBox history first
/professions rejuvinator <inspect|delivered|cancel> <player UUID>Review an interrupted Rejuvinator purchase. It issues no items and refunds nothing

Test tools

The /professions test subcommands change only your own character: /professions test <profession> <level> and /professions test level <profession> <level> set your XP to that profession level (1 to 100, capped by curve.cap), /professions test threshold <profession> <level> sets your XP one point below that level (level 2 up), and /professions test kit delivers a cooking test kit (tools, ingredients and recipe scrolls). Bare /professions test prints this usage. They grant no level-up rewards. They work only when testing.commands is true in config.json (default false) and the sender is an admin or holds scuffedprofessions.test. Keep them off on live servers.


Permissions

Nodes are declared in code. The plugin writes no permission block to a manifest.

NodeEffect
scuffedprofessions.adminAll admin commands and Admin View. Operators always pass
scuffedprofessions.useLets a player reset a tree with /professions reset <profession>. Without it, players use the Reset button on the profession page. Operators always pass
scuffedprofessions.testUse the test tools (together with testing.commands)

Notes:

  • Wildcard and negated nodes (scuffedprofessions.*, -scuffedprofessions.admin) are read the way the engine reads them.
  • A provider failure reads as "no access", never as access.
  • The /professions, /professions leaderboard, /professions boost, /professions attune and /alchemy commands need no node. The first four are opened to the hytale:Adventurer group.
  • Titles: master titles use the node endlesslink.title.master_<profession>, granted through LuckPerms when the player reaches 100.
  • Shop unlocks: Building level rewards write LuckPerms nodes named shop.unlock.<set> (see Building shop unlocks). The plugin only ever removes nodes it granted itself.
  • Boost templates can carry their own permission node for in-game purchase.

Configuration

All files are under mods/ScuffedProfessions/. Admin View exposes the common values in the normal professions menu, edits go into a draft and apply on Apply, stale drafts are refused, and dated backups keep older revisions. Hand edits need /professions reload. Provider and startup settings may need a restart.

FileControls
config.jsonEnabled professions, XP multipliers and curve, boosts, anti-farm guards, feedback, integrations, exploration, storage
xp/<PROFESSION>.jsonPer-profession action, item and block XP tables (MINING.json and so on)
rewards/<profession>.jsonTiers, pick counts, options, fixed rewards, rare finds, capstones
gates.jsonLevel requirements on supported crafting and use actions
cooking.json, alchemy.json, drops.jsonRecipes, tuning, custom ingredient sources
relics.json, excavation.jsonRelic odds and issuance windows, GAIA, exposed finds, restoration, artifact contents
keepsakes.json, reforge.json, vaporiser.jsonTool replacement, Smithing reforge, salvage
capstones.json, capstone_world.jsonCapstone fees and placed effects
exploration-places.jsonOperator-defined landmarks (starts empty)
text.json, lang/Wording and language overrides
packs/Optional content packs
xp-reset.jsonXP reset campaign window (see below)
settings_sync.jsonWritten by the settings sync; records what the server last agreed

Migrations back up the previous file next to it (for example config.json.pre-antifarm-guards.bak, *.pre-base-xp-v<version>.bak). Earned XP, levels, choices, claims and running boosts are never rewritten by a migration. Keep rewards.preserveOnMigrate on if you plan to merge changed reward defaults by hand.

Core settings (config.json)

KeyDefaultMeaning
curve.base / curve.scale / curve.cap300 / 200 / 100XP curve. Level 100 needs about 11 million cumulative XP at these values. Base 1 to 1,000,000, scale 0 to 1,000,000, cap 2 to 1,000
curve.postCapStep0XP per level after Transcend. 0 derives it from the level 99 to 100 step
skills.<SKILL>.enabledtrueA disabled skill keeps its stored data but earns nothing and is hidden
skills.<SKILL>.xpMultipliersee belowMultiplier on the profession's XP table
skills.<SKILL>.fortuneEnabled / rareFindsEnabled / durabilityEnabledtruePer-profession switches for fortune, rare finds and durability tree lines
skills.<SKILL>.statRowsEnabledfalseWhether legacy attribute rows in the profession's tree are offered. The reviewed stamina and health choices stay available either way
skills.<SKILL>.gatesEnabledunsetOverrides gates.enabled for one profession
routing.blockBreakPriorityMINING, WOODCUTTING, EXCAVATION, FARMINGWhich skill claims a broken block, first match wins. A -1 row in an earlier skill stops later ones
worlds.<world>nonePer-world xpMultiplier and disabledProfessions. A key also matches every instance of that world (instance-<key>-...)
transcend.enabledtrueShow the Transcend button
transcend.announcetrueChat line when someone Transcends
transcend.announceScopenetworknetwork (every linked server) or server
leaderboard.enabledtrueLeaderboard page and rank placeholders
leaderboard.refreshSeconds600How stale a rank may get
leaderboard.maxPlayers5000Ceiling on one scan
integrations.endlessQuests.enabledtruePublish profession counters for EndlessQuests external-counter quests
gates.enabledfalseMaster switch for gates.json level gates
gates.notifyCooldownMs2000Minimum gap between refusal messages to one player
ui.sounds / ui.hudPopups / ui.levelUpToasttrueFeedback switches
ui.soundVolume0.350 to 1
ui.soundCooldownSeconds4.00 to 300
floatingXp.enabled / floatingXp.sizetrue / 1.0Floating XP icon and its size (0.4 to 5)
debugfalseVerbose logging, including per-press building lines
testing.commandsfalseEnable the test tools
xp.repairEmptyTablestrueReplace an XP table that parses to zero entries with the bundled default (old file kept as .empty.bak). Set intentionallyEmpty inside a table to keep it empty
xp.richYieldPercentile60Percentile used by rich-yield tree lines

Default xpMultiplier per profession: Mining 4, Woodcutting 0.6, Excavation 10.5, Farming 0.33, Fishing 10, Building 15, Smithing 0.65, Alchemy 3, Cooking 54, Husbandry 150, Exploration 2, Acrobatics 10. Values accept any finite number from 0 up; there is no upper clamp, and 0 pays nothing. A gain under one point is kept and added to the player's next gain. The shipped XP tables use MMOSkillTree 1.6.0 values as their base, with ore, wood and crop tiers scaled by this mod.

Profession-specific settings

KeyDefaultMeaning
farming.handPickShare0.25Share of a crop's row paid for a ripe crop picked by hand (0 to 1; 0 disables)
farming.areaFullCrops6Tiles of one area-tool swing that pay in full (1 to 1,024)
farming.areaExtraShare0.25Share paid for later tiles in the same swing (0 to 1)
farming.registerVanillaHarvestCodectrueWrap vanilla's HarvestCrop interaction so right-click harvests pay
farming.breakEventExcludedPrefixes["Plant_Crop_"]Block ids that never pay through the break event
fishing.failXp0Raw XP for a failed catch
fishing.levelPowerBonus2.0Fishing power added to the Almanac roll at the level cap (0 to 10). Providers without a power-aware roll ignore it and log once
building.claimSplit.ownClaim / wilderness / otherClaim / unknownProvider1.0 / 0.5 / 0.0 / 0.5Multiplier on Building XP by where the block lands
building.recentPlacements.size / windowSeconds / radius128 / 600 / 1Recycle-debt window: breaking a paid placement within the window holds back the builder's future Building XP
building.bulkPlacement.enabledtrueDrag and fast-click guard
building.bulkPlacement.modeenforceenforce, or observe to log what it would cut while paying as before
building.bulkPlacement.dragCellShare0.035Share paid for each further block of a drag, or a press sooner than the interval
building.bulkPlacement.minFullPressIntervalMs1500Minimum gap between full-paid presses
building.bulkPlacement.pressWindow / sameBlockPresses / sameBlockFactor24 / 20 / 0.85If 20 of the last 24 presses used one block, each pays 85%
smithing.benchIdsFurnace, Weapon_Bench, Armor_Bench, Armory, WorkbenchBench ids whose crafts pay Smithing
smithing.refundEnabledtrueServer-wide switch for the Frugal Smith option
alchemy.benchIdsAlchemybenchBench ids whose crafts pay Alchemy
cooking.stationBlockIdsSP_Cooking_StationBlocks a cook can start a pot on
cooking.fire.decay / rise / fall / stoke / drift / driftInterval0.60 / 0.20 / 0.10 / 0.12 / 0.16 / 2.6Heat-feel tuning, ranges 0.02-4, 0.02-2, 0.01-2, 0.01-2, 0-0.4, 0.2-30. Out of range values are ignored with a warning
acrobatics.minFallDamage5.0Least fall damage that pays
acrobatics.maxCreditedDamage60.0Most damage one fall is paid for (on a 100 point health pool)
acrobatics.perfectDodgeEnabled / perfectDodgeInPvptrue / trueDodge XP switches (needs Perfect Dodges)
acrobatics.dodgeHourlyXpCap20000Hard ceiling on dodge XP per player per hour; 0 removes it
collapse.enabledtrueExtra credit for felled logs and area tools. False disables both
collapse.areaToolExtraXpFraction0.05Share a Prisma area-tool extra block pays (0 to 1)
collapse.radius / verticalRange / gapMs / maxBlocks6 / 64 / 1500 / 256Bomb and fire attribution window
collapse.maxLifetimeMs8000Tree snapshot lifetime (up to 4,096 connected logs)
remotePull.enabled / maxRadiustrue / 5Supply Reach and the Supply Network capstone. Radius ceiling is 5 and EndlessGuilds clamps it again
refining.enabled / maxSpeedtrue / 3.0Faster Refining. benches maps Furnace, Salvagebench to smithing and Tannery to husbandry
craftingCapstone.enabled / level / professions / announcetrue / 100 / smithing, alchemy, cooking / trueThe Supply Network capstone, granted once ever
rewards.rejuvinatorLevel90Mining and Farming threshold for the Rejuvinator (multiple of 10, 10 to 100)
rewards.preserveOnMigratefalseKeep an old reward file live instead of migrating it
rewards.crateKeyCommandlootbox givekey {player} mythos 1Console command a $crateKey reward row runs. Empty turns those rows off
rewards.crateKeyName / crateKeyIconMythos KeyDisplay name and icon for that reward
rareFinds.purseXpPerPayment24000XP per coin payment at a 1% Rare Finds card. purseMin 12000, purseMax 18000 (0 turns payments off), purseRoundTo 100, purseFullXpPerMinute 2000, purseExtraShare 0.1. Nothing rolls without an economy plugin

Exploration

KeyDefaultMeaning
exploration.hourlyXpCap0Ceiling on raw repeat XP per player per hour; 0 means none. First discoveries bypass it
exploration.chestDailyCap60Paid chest deliveries per player per UTC day
exploration.riftSourcesgate, fate_zoneWave-completion source ids that count. An empty list disables them
exploration.questIdPrefixesworld_Quest ids eligible for Exploration XP
exploration.receiptDays30Age at which receipts of retired chest fills expire
exploration.maxOpenedPerWorld / maxPlacedPerWorld200000 / 50000Bounds on the chest ledgers
exploration.chestTierLevels, chestTierWeights, chestDungeonTierWeights, chestBlockMinTiers, chestSalt, chestTierLoot, chestSwap, chestOpenParticleshippedChest tier and loot tables for E to S. Chest tiers never restrict ordinary loot by level
exploration.content.*shippedWorld and instance allow-lists, quest, dungeon and raid source rows, maxVolumeChunks, and glint.enabled (12 block radius, 6 seconds between player writes)

Fate Zone clears take their rank from the run's level band when EndlessFates exposes it: E below level 25, C below 60, A from 60. The limits are exploration.content.earlyLevelLimit (25) and exploration.content.lateLevelStart (60). A claim that spends a Fate charge pays the action row fate_complete_<rank> (shipped 750, 1,500, 3,000 for E, C, A), a claim with no charge or XP only pays fate_assist_<rank> (125, 250, 500), and the first clear of a rank pays fate_first_<rank> instead (4,500, 9,000, 18,000). These rows live in xp/EXPLORATION.json and are raw XP before the multiplier. To add landmarks, edit exploration-places.json. Each places entry has world, a permanent id, nameKey, tier (E to S), and min and max arrays of three coordinates. Keep ids stable when changing bounds. Earned-chest, clear and quest reward queues are stored under exploration-pending. Keep them in server backups.

Anti-farm guards (antifarm)

Several guards are kept in memory only: they survive a relog but not a restart.

KeyDefaultMeaning
antifarm.miningRepeatPositionMinutes30A mined position pays once in this window (0 to 10,080; 0 disables)
antifarm.tameCooldownMinutes1440Re-taming the same animal pays once in this window (0 to 43,200)
antifarm.landingSpotMinutes10A survived fall pays once per player per 8 by 8 column (0 disables)
antifarm.animalCredit.feed / harvest / breeding9 / 1 / 1Minutes before the same animal pays the same Husbandry action again for its owner (0 turns one off). At most 4,096 animals per owner
antifarm.tripwire.enabledtrueBackstop per player and action over any 60 seconds, counted in final XP
antifarm.tripwire.perMinutesee belowLimit per action. A missing action or 0 is not watched
antifarm.ledger.enabledtruePlaced-block ledger: blocks placed by a player or worker pay no XP when broken in the window
antifarm.ledger.expiryMinutes120Window length
antifarm.ledger.maxEntriesPerWorld200000Soonest-expiring entries are evicted past this
antifarm.ledger.exemptItemPrefixes["Plant_Seeds_"]Items not recorded, so crops grown from seeds always pay
antifarm.diminishing.*offShared fade (windowMinutes 60, fullCount 20000, decaySpan 20000, floor 0.5) and perSkill overrides. Off for every skill by default
antifarm.pace.<SKILL>noneOptional per-minute budget: the first fullPerMinute units pay in full and the rest pay extraShare. No skill ships one

Default perMinute tripwire limits are 40,000 for COOKING:dish, FISHING:catch, HUSBANDRY:feed, HUSBANDRY:harvest, HUSBANDRY:breeding, HUSBANDRY:combat, ACROBATICS:fall, SMITHING:vaporiser and FARMING:harvest, and 120,000 for SMITHING:craft. A trip pays up to the limit, pays nothing beyond it and logs one WARN line naming the player. Furnace and other processing payouts and first-time awards are never counted.

XP evidence and balancing

Each server logs its own XP payouts by player, profession and method (break:Ore_..., craft:..., area:, collapse:, fall:) for 14 UTC days in xp_evidence.json. /professions admin evidence turns that into suggested table or multiplier changes and writes reports/xp-evidence.txt and .csv (rewritten every hour). The suggestions are Cut (a method would take players to 100 faster than the floor), Lower or Raise (typical pace outside the target range), Review and Collect (not enough players yet).

KeyDefaultMeaning
xpEvidence.enabledtrueRecord payouts
xpEvidence.retainDays14Days kept
xpEvidence.windowDays7Default report window
xpEvidence.bridgeMinutes5Gaps up to this count as continuous work
xpEvidence.floorHours10No single method should reach level 100 faster than this
xpEvidence.targetMinHours / targetMaxHours100 / 200Target time to level 100 for a typical player. targetHours.<SKILL> overrides per skill as [min, max]
xpEvidence.minMinutes / minMethodMinutes / minPlayers30 / 10 / 3Thresholds for counting a player, a method and a suggestion

After changing a table row or pace budget, run /professions admin evidence reset [--profession <skill>] twice within 10 seconds so old play does not blend in. A multiplier change needs no reset.

First finds (firsts)

KeyDefaultMeaning
firsts.enabledtrueGathering, crafting and taming first-find bonuses
firsts.<kind>ore 20, wood 10, crop 10, fish 10, dish 5, brew 5, animal 5, chest 0.5, rift 0.5Base XP multiplier for that kind; 0 disables it. Chest and rift firsts use the Exploration action rows instead
firsts.catalog.<kind>automaticRestrict a kind to a list of canonical ids (Wood_Oak, Plant_Crop_Carrot, a loot id for fish). An empty array disables the catalog

Provider catalogs refresh within 30 seconds after startup and on reload. Only current eligible finds count toward the displayed percentage.

Storage settings

KeyDefaultMeaning
storage.sharedBackendtrueUse the Endless Leveling shared backend when it offers one. False forces the local database
storage.namespacescuffedprofessionsServers share data only with servers on the same namespace
storage.syncXpSettingstrueKeep every skill's xpMultiplier and antifarm.pace rows the same across servers on the shared backend. A change reaches the others within about a minute. The file before the first write is kept as config.json.pre-settings-sync.bak
storage.retryMillis60000Retry delay after a storage failure (5,000 to 3,600,000)
storage.localFileprofessions.dbLocal database file name

Boosts and store setup

A boost is never personal. Whoever buys it, every player gets the extra XP and the buyer is credited on the HUD badge and in the announcement.

Key (boosts.*)DefaultMeaning
maxMultiplier2.0The most XP can be multiplied by, all boosts together
maxDurationMinutes1440Longest single purchase. Several purchases can add up to more
stackingmultiplyPurchases multiply the current rate. Legacy add and highest settings are ignored
inGamePurchasefalseLet players buy templates with in-game coin using /professions boost <name>
storeUrl / storeLineempty / Buy a boost for everyone at {0}Address and line shown on the Boosts page and in /professions boost
networkWidetrueRun every boost on every server sharing the backend (restart to apply)
syncSeconds10How often a server reads the shared table (2 to 300)
txnRetentionDays30How long a transaction id is remembered
announceStart / announceEndtrueChat announcements
templatesprofession_60, all_60Each has skill (a profession id, * or choose), multiplier (1.15), minutes (60), label, and for in-game buying price, cooldownMinutes, permission

Store commands for a purchase (run as an offline command; the buyer need not be online):

professions boost grant all_60 {username} --txn {transaction}
professions boost grant profession_60 {username} cooking --txn {transaction}
  • Always pass --txn. It is the replay guard: the same transaction id delivers one purchase across servers, and a retry on another server is refused. A --txn value that still contains { or } is ignored with an [SP][AUDIT] ... UNUSABLE --txn id line and the boost starts without protection.
  • Purchases multiply the running rate and add their time: at 1.15x with 30 minutes left, another purchase gives 1.3225x for 90 minutes. The fifth purchase reaches the 2x cap and further purchases only add time.
  • Renewing within ten minutes of expiry multiplies the previous rate and starts a fresh hour. The gap pays normal XP.
  • If the shared backend is down, a paid purchase waits in boost_queue.json and starts on every server with its full time once the table answers. An unreadable queue is kept as boost_queue.json.unreadable-<time> with a SEVERE log line.
  • Each server records used transaction ids in boost_txns.txt too, so a replay during an outage is still refused.
  • Reply lines start with Started #<id>, Already started, Recorded (saved, starts when the table answers, do not refund), WARNING: --txn id ignored or FAILED: .... After fixing a FAILED package, run the corrected command by hand with the same --txn value.
  • Stopping a boost does not refund money. Upgrade every participating server together; an older jar does not understand cumulative totals.

Content packs

A pack adds to the profession tables without editing the files in mods/ScuffedProfessions/. Another mod can ship a pack inside its jar, or you can drop loose files in. Packs are read at boot and on every reload, and the log lists the files used and any problems.

  • Inside any .jar or .zip in mods/, at Server/ScuffedProfessions/<Kind>/<name>.json.
  • Loose, at mods/ScuffedProfessions/packs/<pack>/<Kind>/<name>.json.

<Kind> is XpMaps, Rewards, Drops or Vaporiser. Packs apply after your own files: jars and zips in file-name order, then loose packs in folder-name order. Every file may set "mode": add (default, merges key by key, pack wins on a clash, lists are added to) or replace (discards that section of your file and uses the pack's).

KindPurpose
XpMaps{ "skill": "mining", "entries": { "Ore_Mithril": 90 }, "actions": { } }. A key matches an exact id first, then the longest key ending in _ that the id starts with, then the longest key the id contains. A negative value claims the id and pays nothing
RewardsrareFind entries and levelRewards rows for one profession, at any level. Row types: item, command (needs a description), title, blessing, unlock, bonus, fortune, rare_find, xp_bonus, durability, stat
DropsIngredient and scroll drops: mobs, bosses, raids, events, chests, fishing, hoard, each entry with item, chance (0 to 1) and optional min, max
Vaporiserrarity rows (item id to a rarity number) merged into vaporiser.json. Packs cannot set baseWorthLowest or the payout formulas

Reward row notes:

  • "repeatable": true fires the row again on every climb after Transcend (blessings repeat by default).
  • "scope" on a command, title or blessing row is network (paid once for the whole network on the server where the player levelled) or server (paid on each server). Commands and blessings default to per-server, titles to network. Items are always per server. Any other word is an error.
  • Command rows replace {player}, {user} or %player% with the player's name.
  • "retroactive": true grants a newly introduced row to players who passed the threshold earlier.

ScuffedProfessions ships a few packs of its own (Alchemy reagents and herbs in rare finds, level 90 finds, reagent drops, Alchemy refining XP, and two Drops packs). A pack of yours with "mode": "replace" overrides them.


Building shop unlocks

At certain Building levels a player earns a LuckPerms node shop.unlock.<set>. Nothing is locked until your shop listings ask for the node.

LevelNodeSuggested contents
10shop.unlock.builders_woodworkBranches, roots and leaves
20shop.unlock.builders_cornerRoyal Magic furniture, cloth roofing and roofs
30shop.unlock.lost_civilizationThe Human Ruins set
50shop.unlock.village_fittingsBrazier, construction sign, training dummy
70shop.unlock.temple_masonryForgotten gateway, aqua brick

Nodes are checked on join, on level-up and when an admin changes a level, and an XP reset or lowered level removes the nodes the new level no longer covers. Transcending Building keeps every set. LuckPerms is shared across a network, so servers sharing a LuckPerms database share the unlocks. You can hand a node out yourself (/lp user <name> permission set shop.unlock.temple_masonry true) and the plugin will not remove it. To change the sets, edit the unlock rows in rewards/building.json (id becomes the node name, where is the line shown in the tree, "enabled": false removes it for everyone on their next check) and reload. An unlock row can be added to any tier of any profession.


Gates (gates.json)

Level gates are enforced only while gates.enabled is true (or skills.<SKILL>.gatesEnabled for one profession). The shipped file gates the four high-tier metals, by ore for Mining and by bar for Smithing: Mithril at level 40, Adamantite at 55, Thorium at 70 and Onyxium at 85. Shape:

"MINING": [ { "level": 40, "ids": ["Ore_Mithril"], "message": "gate.mining.mithril" } ]

ids match by prefix (the broken block id for Mining, Woodcutting, Excavation and Farming, the placed block id for Building, the recipe id for Smithing and Alchemy). The highest matching level wins. A refused action is cancelled with a short message.


Capstones and recovery

capstones.json holds attuneFee and remakePrice per profession (25,000 each by default), announceDraw (true), and two power blocks:

KeyDefaultMeaning
gatecaller.sRankChance0.005Chance the Gatecaller's Sigil opens an S gate with one player online
gatecaller.sRankPlayerFalloff1.0The S chance is divided by the number of players online raised to this power (0 turns the scaling off, maximum 4)
gatecaller.sRankFloor0.0001Lowest the S chance goes
gatecaller.aRankShare0.55Of the gates that are not S, the share that are A; the rest are B
gatecaller.announcefalseLet Endless Rifts announce the gate to the whole server and offer a free teleport to an S gate
leviathan.despawnSeconds300How long a Leviathan stays before it slips back (30 to 3,600)
leviathan.shoreRadius12How far from the bobber it looks for dry ground (4 to 32)
leviathan.roleSP_LeviathanNPC role it spawns as

An S roll opens an A gate instead while an S gate or S-Gate event is already running. Each use is once per UTC day per server copy. On a server with no economy, attuning and remaking are free. capstone_world.json holds heartwood.regrowHours (6) and trinketsmith.cooldownDays (7), plus the trinket recipe list.

Capstone state is stored in capstone_ledger.json, capstone_placements.json, capstone_trades.json, capstone_stumps.json and related files, or in the shared backend when one is active. Do not delete player, purchase, artifact, capstone or delivery records to change balance.

Recovery workflow for a capstone loss, mistaken sale or wrong holder:

  1. /professions admin capstonehistory <profession> <number> to read the custody history.
  2. /professions admin capstonerepair <profession> <number> <recipient|revoke> "reason" for a preview and token.
  3. /professions admin capstoneconfirm <token> within 60 seconds as the same admin. A changed ownership invalidates the preview, older copies on this server become void (a placed copy too, so inspect terrain), and a replacement waits durably for the recipient to join.
  4. Use another recorded repair to compensate for a mistaken repair.

Other recovery tools:

  • admin diagnose and admin reconcile for stuck deliveries, admin xp ... get/set/add for wrong XP, admin perk and admin claims reset for tree repair.
  • admin boost stop and admin boost resolveorder for wrong or uncertain boosts.
  • /professions artifact for relics and revival incense, /professions admin vaporisation for A/S Vaporiser destructions, /professions rejuvinator for an interrupted station purchase.
  • Cooking pots, forge sessions, economy receipts, remote terrain and provider-owned animal records need their own evidence. The tools do not invent a lost item, clear an unresolved payment or reset a cooldown based on a player's report alone.

Data & storage

  • Player progression (XP, levels, tree choices, Transcend flags, collections, boosts and capstones) is stored in the Endless Leveling shared backend when it is active, so servers on the same storage.namespace share levels, though not items or money. Otherwise it is stored locally in professions.db under the data folder. A server that previously used shared storage waits for it to return instead of starting a separate local count.
  • Reset credits live in the entity namespace scuffedprofessions-tree-resets on shared storage, or in tree-resets locally. Switching from local reset wallets to shared storage is blocked until those wallets are migrated; there is no automatic merge. Keep profile and wallet backups together.
  • Server-local state files include rejuvinator_claims.json, furnace_owners.json, forge_benches.json, vaporisation-history.json, purse_payments.json, coin_pouches.json, tablet_readings.json, boost_queue.json, boost_txns.txt, exploration-pending.json and xp_evidence.json. Amalgamation uses are recorded in shared storage when enabled, or locally in amalgamation_uses.json. Do not remove that ledger to recover a player's food, because a spent meal could become usable again.
  • Items, claims and rewards are per server. Each server pays a player the reward rows their levels earned once, even if they levelled elsewhere.
  • Backup sets and the checkpoint audit hold private player data. Keep them out of Git and public downloads.

Backups

Professions registers as professions in the Endless Leveling suite backups. EL takes a startup checkpoint and then one each hour. Retention keeps 48 hourly, 14 daily, 10 startup, 20 manual and 20 safety sets. Each Professions checkpoint holds saved player progression, reset balances, local JSON settings and state, and language files, plus (on shared storage) capstones, server-local rewards, legacy claims, relics, revival incense, Amalgamation uses and boosts.

  • Every payload has a SHA-256 checksum, verified before a checkpoint is listed as usable. Failed exports keep the previous good sets.
  • If EL's suite API is unavailable, checkpoints go to backups/checkpoints/ under the data folder with the same retention. A delayed check runs three minutes after startup if no usable checkpoint exists. There is no shutdown backup.
  • These are local recovery points. Off-server backups stay the operator's job.
  • EL's /el backup includes Professions, but EL's broad restore commands report Professions as unsupported and direct you to the selective commands below.

Selective restore: backup restore latest <player> <profession> xp,tree "reason" writes nothing and prints a token. backup confirm <token> first takes and verifies a safety checkpoint, checks for changes since the preview and then applies. Each result is recorded in checkpoint-audit/. XP restore recalculates levels with the current curve. Tree restore keeps the combined choice history. Reset restore keeps current grant receipts.

  • Targets must be offline. With shared storage keep them offline on every network server and add --network-offline true. The plugin cannot verify another server's live session.
  • Checkpoint namespace, server scope and storage lane must match. These commands do not migrate backups between networks.
  • A restore keeps current item-delivery and reward-command receipts, inventories, money, boost purchases and timers, capstone numbers and custody, cooldowns, collections and recipe discoveries. It never replays reward commands or mints capstones.
  • If a player's whole profile is missing, receipts, collections and discoveries are recovered and a recovery hold blocks XP, tree changes and reward delivery until an admin reviews post-checkpoint payouts and runs backup releasehold.

XP reset campaign

/professions admin resetandcompensate lowers profession XP earned under looser settings to what the same play pays today. It does not cap a pace or a level. The window is set in xp-reset.json: campaign, since (start of the window), maxIntervalHours, keepXpBeforeSince (false by default) and historyDirs (relative folders holding backup sets copied from sister servers).

  • XP logged in xp_evidence.json is repriced per payout at today's row and multiplier.
  • Gains before the log, or seen on another server, are revalued at today's multiplier against the lowest multiplier any running server had.
  • Nobody is raised above the XP they had at the cutoff, transcended rows are kept, and a gain above what the log paid stays as earned.
  • The first run only previews and writes every row to a report. Confirm within 120 seconds with the printed token. Later runs move players only by the difference.

Excavation, Smithing and other tuning files

  • excavation.json: findChance 0.005, maxExposedFinds 32, restoreStrokes 3, restoreXp 150, firstFindXp 250, highTierChance 0.02, highTierTrinketShare 0.5, highTierVoidstoneWeight 1 (0 disables Voidstone), tabletLevelFraction 0.05, abandonedJobHours 24, keenEyeCap 0.9, prospectorTin (min 3, max 5, ores), coinPouch (min 150, max 350), frostCache, siftOres (copper 3, iron 1) and per-terrain artifacts weights.
  • vaporiser.json: rarity rows, hourlyXpCap (0 by default, no ceiling), bag.payoutShare and bag.xpShare (both 1). No weapon ever pays more than 100,000 lowest-tier cores. A/S destruction history is kept 30 days or 5,000 records.
  • alchemy.json: recipes, costs, levels and grade durations. Hunter's Flare duration is capped at 60 seconds, and radius and enemy count have fixed ceilings. One flare per player, four per world and sixteen per server can be active.
  • cooking.json: recipes, ingredients and the amalgamation object (mastery level 95, duplicate scale 0.05, minimum quality 0.90, duration 3600 seconds, 24 attribute points, restored health 0.50, protection 3000 ms). The duplicate scale, duration and protection time cannot be raised above those defaults.
  • Vault keys: the six rank costs, Smithing levels and XP actions (forge_vault_key_e to forge_vault_key_s in xp/SMITHING.json) are defined in this mod; the key items themselves come from Endless Rifts.

Integrations

PluginTypeUse
EndlessLevelingCoreRequiredProgression storage, attributes, menu navigation (the Professions tab), language selection, suite backups
LuckPermsRequiredShop unlock nodes and master title permissions
AnglersAlmanacOptionalFishing XP, Quick Bite, fishing potions, Leviathan summons
FarmingPlusOptionalFarming actions, the Sickle capstone, Growth Tonic
Tamework (Alec's Animal Husbandry)DetectedTaming, feeding, breeding and produce XP; animal draughts; Golden Halter
Perfect DodgesOptionalDodge XP for Acrobatics
EndlessForgedOptionalForged weapon upgrades, Vaporiser eligibility and currencies, trinket equipment, soulbound capstone trades
ScuffedNPCsOptionalMining sites, guild blessings, Rejuvinator worker supplies (capacities and worker travel are owned there)
EndlessGuilds / ScuffedProtectionOptionalClaim checks, guild supply access, claim flight, GAIA spawn filtering, Supply Network
EndlessMarriageOptionalRecorded one-use NPC spouse revival. Profession XP is never spouse-shared
EndlessRifts / EndlessEventsOptionalExploration completions, Treasure Finder grants, Breach vault key items for the Forge Bench, Gatecaller's Sigil
EndlessFatesOptionalFate Zone clear payouts
EndlessDurabilityOptionalDeath wear reduced by Equipment Care and Workshop Care
BetterLootBoxOptionalMythos key claims with delivery confirmation
Condensed Crops packDetectedThe Amalgamation recipe
EndlessQuestsDetectedProfession counters for external-counter quests (integrations.endlessQuests.enabled)
ZenShop or any shop that reads permissionsExternalLock listings behind shop.unlock.<set> with requiresPermission
PlaceholderAPIDetected%professions_*% placeholders (see below)

Missing optional integrations disable their feature and never grant another player your XP. Third-party controls and configuration stay in the owning mod.

Placeholders

The professions expansion registers when PlaceholderAPI is present (see the PlaceholderAPI guide).

PlaceholderValue
%professions_total_level% · %professions_total_xp% · %professions_total_lifetime%Sums across all professions
%professions_rank_total%Rank by total
%professions_level_<id>% · xp_<id> · lifetime_<id>Level, current XP, lifetime XP in a profession
%professions_transcended_<id>%Whether the profession is Transcended
%professions_rank_<id>%Leaderboard rank in a profession
%professions_top_<id>_<n>% · %professions_top_total_<n>%Name at rank n (1 to 10)
%professions_first_<id>%Name of the No. 1 capstone holder
%professions_minted_<id>%Numbered capstones that exist
%professions_capstone_<id>%The player's capstone number, or empty

<id> is mining, woodcutting, excavation, farming, fishing, building, smithing, alchemy, exploration, cooking, acrobatics or husbandry.


Languages

English ships in the jar. For runtime overrides use mods/ScuffedProfessions/lang/<locale>.lang with underscores (for example lang/es_ES.lang); missing keys fall back to English. text.json is a flat language-independent override map that takes precedence. Keep keys, item ids, command tokens and {0} placeholders unchanged. Run /professions reload and reopen the page. Native item and UI changes in an asset pack may also need an asset reload or a restart. Custom recipe and ingredient names use the keys alchemy.brew.<item-id>, alchemy.reagent.<item-id> and cooking.ingredient.<item-id>.


API for other mods

Use com.zbeve.scuffedprofessions.api.ScuffedProfessionsAPI. All members are public static, so a call works without holding an instance.

AreaMethods
ReadinessisReady(), hasData(uuid)
ReadgetLevel, getXp, getLifetimeXp, getLevelProgress, xpIntoLevel, xpForNextLevel, isTranscended, getAllXp, getAllLevels, getTotalXp, getTotalLevel, xpForLevel, levelForXp, getProfessions
CapstoneshasCapstone, holdsCapstone, carriesCapstone, capstoneWorksFor, transcendedCount
Leaderboardleaderboard(profession, limit)
Award XPaddXp(uuid, profession, amount, reason), award(...) (returns PAID, HELD_AT_CAP, BANKED or REFUSED), awardFinal for a displayed final amount
EditsetXp, removeXp, setTranscended
Treeclaims, claim, resetClaims, bonus(uuid, skill, key)
EventsaddXpListener, addLevelUpListener, addTranscendListener and matching remove methods (ProfessionXpEvent, ProfessionLevelUpEvent, ProfessionTranscendEvent)

Rules for callers:

  • Read-only consumers can query levels, XP, Transcend state and tree bonuses without issuing XP.
  • Use addXp only for a confirmed action by the supplied player. The source identity matters for anti-farming and audit. Do not award viewers, nearby players, spouses or unknown furnace owners.
  • It returns false and changes nothing when the profession or world is off, the amount is not positive, the player is in Creative (admin grants excepted) or the gain is under a whole point after the multiplier (the fraction is kept for the next gain).
  • Resets spend one credit for that profession. Use the admin recovery tools for capstone and artifact replacements. Raw item creation does not produce a valid numbered copy.
  • Configuration and reward records are not stable integration APIs. Register content through packs where possible, compile against the versions you deploy and test missing-provider behavior separately.

Troubleshooting

SymptomCause and fix
The plugin does not loadLuckPerms or EndlessLevelingCore is missing or too old. Check the versions under Requirements
/professions reload says to check the logA JSON file is malformed. Nothing was applied. Fix the file and reload
A profession shows no XPThe profession is disabled in skills, the world lists it in disabledProfessions, or the player is in Creative
Players get no XP from placed blocks, cave spots or repeated actionsWorking as designed: placed-block ledger (120 minutes), mining repeat window (30 minutes), animal credit windows and landing-spot window
A player's profile reads as missing after a restoreA recovery hold is set. Review payouts and custody, then backup releasehold
A capstone does nothing on another serverA copy works only on the server that made it. The player claims a copy on each server
A boost purchase did not startCheck [SP][AUDIT] lines. Recorded means it waits for the shared table; FAILED means rerun the corrected command by hand with the same --txn
Tame XP does not payTaming the same animal again pays once per antifarm.tameCooldownMinutes, and claiming an already-tamed animal is not a tame. Check the Tamework version
Config edits are overwritten on another serverstorage.syncXpSettings shares xpMultiplier and antifarm.pace across servers on the same namespace. Edit the value on one server or turn the sync off
A reward claim shows CheckUse /professions rewardclaims list <uuid> -, verify the provider history, then retry or settle