Sarcina (In-Depth)
The exhaustive Sarcina reference — every capacity, autosell, and multiplier formula with level breakpoints.
This is the exhaustive Sarcina reference — every formula, every level breakpoint, every interaction with the economy pipeline. If you only want the short version, see Sarcina Backpack. If you want to optimize a multi-million Auctoritas spend, you're in the right place. All numbers below come straight from SarcinaManager.kt and the matching config keys in config.yml.
The Three Upgrade Paths — At a Glance
| Path | Effect | Cost Currency | Base Cost |
|---|---|---|---|
| Capacity | Backpack holds more blocks before overflowing | Auctoritas ⛁ | 10,000 per level |
| Autosell | Sells contents on a timer (eventually instantly) | Auctoritas ⛁ | 50,000 per level |
| Multiplier | +1% sell value per level | Auctoritas ⛁ | 10,000 per level |
All three are independent — your Capacity level has no effect on your Autosell or Multiplier level, and each has its own cost curve. You can spend tokens on any of the three at any time, in any order.
Capacity — The Doubling Curve
Formula
capacity(level) = capacityBase × 2^level
where capacityBase = 100 (config: pouches.default_capacity) and the level is bounded to [0, 60] (config: pouches.max_capacity_level).
cost(level) = capacityCostBase × 2^(costExponent × (level-1))
where capacityCostBase = 10,000 (config: pouches.upgrade_cost_base), costExponent = 2 (config: pouches.upgrade_cost_exponent), and the (level-1) exponent is capped at 22 in code so costs plateau rather than overflow.
The exponent cap means costs stop growing after level 23, but capacity keeps doubling all the way to level 60. This makes very high capacity levels disproportionately cheap in tokens-per-block — a deliberate endgame efficiency incentive.
Level-by-Level
| Level | Blocks Held | Total Tokens to Reach |
|---|---|---|
| Lv 0 | 100 | 0 |
| Lv 1 | 200 | 10,000 |
| Lv 2 | 400 | 40,000 |
| Lv 3 | 800 | 160,000 |
| Lv 4 | 1,600 | 640,000 |
| Lv 5 | 3,200 | 2,560,000 |
| Lv 6 | 6,400 | 10,240,000 |
| Lv 7 | 12,800 | 40,960,000 |
| Lv 8 | 25,600 | 163,840,000 |
| Lv 10 | 102,400 | ~2.62 B |
| Lv 15 | ~3.28 M | ~2.75 T |
| Lv 22 | ~419 M | ~1.13 P (quad max exponent) |
| Lv 23 | ~839 M | ~1.13 P (cost caps here) |
| Lv 30 | ~107 B | ~1.13 P (capped) |
| Lv 60 | ~115 quad | ~1.13 P (capped) |
Autosell — Halving Intervals to Instant
Formula
autosellTicks(level) = 6000 ticks >> (level-1) — equivalent to 6000 / 2^(level-1). At 20 ticks/second, that's 300 s / 2^(level-1).
If the resulting interval drops below 20 ticks (1 second), the value is replaced with -1, which the autosell scheduler treats as "instant" (sells on every block insert, no timer).
cost(level) = autosellCostBase × 2^(level-1)
where autosellCostBase = 50,000 (config: pouches.autosell_cost_base) and the (level-1) exponent is capped at 40.
Level-by-Level
| Level | Sell Interval | Total Tokens to Reach |
|---|---|---|
| Lv 0 | Disabled — manual /sellall | 0 |
| Lv 1 | 5 min (300 s) | 50,000 |
| Lv 2 | 2.5 min (150 s) | 100,000 |
| Lv 3 | 75 s | 200,000 |
| Lv 4 | 37.5 s | 400,000 |
| Lv 5 | ~19 s | 800,000 |
| Lv 6 | ~9 s | 1.6 M |
| Lv 7 | ~4.7 s | 3.2 M |
| Lv 8 | ~2.3 s | 6.4 M |
| Lv 9 | ~1.1 s | 12.8 M |
| Lv 10 | Instant (<1 s) | 25.6 M |
| Lv 12 | Instant | 102.4 M |
| Lv 20 | Instant | ~26.2 B |
| Lv 41 | Instant | ~54.9 T (cost caps here) |
Level 10 is the instant breakpoint. Past that, more autosell levels are pure prestige — they don't change gameplay, only the token-sink leaderboards. If you're optimizing, stop at level 10 and shift spend to Multiplier.
How the Timer Fires
A repeating task runs every 1 second (20 ticks) server-wide. For each online player, it reads the player's autosell level, computes the interval in ms, and triggers a sell if now - lastAutosell ≥ intervalMs. The instant path (level ≥ 10) skips the timer entirely and sells on block insert.
For manual mode (level 0), the Sarcina still auto-sells for you — but on a 2-second cooldown per player to avoid spamming the economy deposit pipeline on fast-mining hot loops. This is what makes /sellall largely optional even without autosell purchased.
Multiplier — Linear Sell Bonus
Formula
multiplier(level) = 1 + level × 0.01
So level 1 = 1.01×, level 10 = 1.10×, level 100 = 2.00×. The bonus is a flat add to the gross sell value, applied before tax.
cost(level) = multiplierCostBase × 2^(level-1)
where multiplierCostBase = 10,000 (config: pouches.multiplier_cost_base) and the exponent is capped at 40.
Level Breakpoints
| Level | Bonus | Effective × | Total Tokens to Reach |
|---|---|---|---|
| Lv 1 | +1% | 1.01× | 10,000 |
| Lv 5 | +5% | 1.05× | 160,000 |
| Lv 10 | +10% | 1.10× | ~5.12 M |
| Lv 20 | +20% | 1.20× | ~5.24 B |
| Lv 30 | +30% | 1.30× | ~5.37 T |
| Lv 41 | +41% | 1.41× | ~5.50 P (cost caps here) |
The Full Sell Calculation — Step by Step
When the Sarcina sells (whether manual /sellall or autosell), the manager runs the following pipeline. Each step is applied in order:
- Sum block values. For each
(material, count)in the backpack snapshot, multiply the block's unit value (fromMineManager.getBlockValue) by the count and sum everything to gettotal. Iftotal ≤ 0, the sell is a no-op. - Apply Sarcina multiplier.
multiplier = 1 + (multiplierLevel × 0.01). - Apply mine-fortune upgrade. If you have a public-mine fortune upgrade stored, multiply the running multiplier by
fortuneMultiplier(). - Apply the EconomyModifierPipeline. This folds in your rank, prestige, pet, crystal, booster, donor, and event multipliers — the entire economy stack. Call
pipeline.getMultiplier(player, DENARIUS)and multiply it in. - Compute gross.
gross = max(0.01, total × multiplier). The floor prevents zero-value sells from creating dead ledger entries. - Compute tax.
tax = round(gross × 0.05 × 100.0) / 100.0— 5% of gross, rounded to the cent (two decimal places). - Contribute tax to the seasonal pool.
serverTaxPoolService.contribute(tax)— the tax vault pays out during festivals. - Net deposit.
net = gross − tax, deposited as Denarius with reasonbackpack:sell(auto) orbackpack:sell_explicit(manual). - On success only — clear the backpack. The snapshot is held until the deposit confirms. If the deposit fails, blocks are not lost — the backpack keeps its contents and you can retry.
- Update player stats. The net amount is added to your
totalEarnedstat (used by leaderboards and stats).
Anti-loss design: the backpack is not cleared until the deposit future returns true. If the DB is briefly unreachable, your blocks stay in the backpack and you can re-trigger a sell. The DB row is also only persisted after success, so a server crash mid-sell preserves the pre-sell (full) state.
Worked Example — A Mid-Game Sell
Suppose you have a Sarcina with multiplier level 5, a mine fortune upgrade of 1.20×, a rank+prestige+pet economy pipeline of 3.50×, and you sell a backpack containing:
- 1,500 stone @ $1 = $1,500
- 200 iron ore @ $8 = $1,600
- 40 diamond ore @ $50 = $2,000
Total block value: $5,100.
| Step | Calculation | Running value |
|---|---|---|
| 1. Sum | 1,500 + 1,600 + 2,000 | $5,100 |
| 2. Sarcina multiplier | $5,100 × 1.05 | $5,355 |
| 3. Mine fortune | $5,355 × 1.20 | $6,426 |
| 4. Economy pipeline | $6,426 × 3.50 | $22,491 (gross) |
| 5. Tax (5%) | $22,491 × 0.05 | $1,124.55 → tax pool |
| 6. Net deposit | $22,491 − $1,124.55 | $21,366.45 to your balance |
The boost summary line will read: Sell Boost: +375% (Sarcina +5% | Prestige +X% | Rank +Y%). Note that the Sarcina-only contribution is small here — the rank and prestige multipliers dominate. That's why Sarcina multiplier upgrades are not the highest-priority spend for most players.
How Blocks Enter the Backpack
addBlock(uuid, material, amount) is called by every block-break code path — the listener that suppresses normal drops, the enchant proc that breaks extra blocks, the pickaxe-skin ability, the mass-detonate ability, and the public-mine listener. The function:
- Skips zero-value blocks — if
MineManager.getBlockValue(material) ≤ 0, returnstrue(block is "accepted") but doesn't store it. This is why some blocks (like grass in a non-grass-valued mine) just vanish silently. - Checks capacity — if
current + amount > capacity, returnsfalse. The caller then drops the block normally into the world so it isn't destroyed. - Otherwise stores — merges into the per-material map and increments the cached
totalBlockscounter (kept current for O(1) capacity checks). - If autosell is instant (level ≥ 10), schedules a synchronous
sellAll(player)on the next tick. Otherwise, in manual mode, schedules a sell on a 2-second per-player cooldown so fast-mining loops don't spam deposits.
Pending blocks for still-loading players: if a block-break fires before the player's backpack has finished loading from the DB, the blocks are queued in pendingBlocks and merged on load completion. No blocks are lost during the login window.
The 60-Second Mining Summary
Every 60 seconds (1,200 ticks) the Sarcina sends a chat summary of the previous minute's activity while you were mining. It tracks nine independent counters and resets them after sending:
| Counter | What it tracks |
|---|---|
| Blocks | Total blocks broken (mining + enchant + ability) |
| Earned (total) | Net Denarius earned (mine income + enchants) |
| ├ Mine Income | Denarius from base block sells (Sarcina) |
| ├ Enchants | Denarius from enchant procs (Denarius Boost, etc.) |
| Auctoritas | Tokens earned (split into Mining vs Milestones when applicable) |
| Crystals | Gemmae crystals gained |
| Civitas | Beacons gained |
| Crates | Crates opened |
| Pouches | Lucky pouches triggered |
The summary only fires if at least one counter is non-zero, so AFK players don't get spammed. Use it to compare mining spots, test build changes, and detect when an enchant proc rate is too low (Enchants line near zero means your build isn't firing).
The Sarcina Item
The Sarcina exists as a physical Ender Chest item in your inventory. It carries a NamespacedKey tag with your UUID, making it soulbound — another player who picks it up cannot use it to access your blocks. Right-click it to open the backpack view.
The giveBackpackItem(player) helper checks whether you already have one (by scanning for the PDC tag) before granting, and drops it on the ground at your location if your inventory is full — so you never end up with two Sarcinas and never lose one to a full inventory.
Persistence & Reload Safety
- The backpack is stored in
backpack_dataas JSON: levels for the three upgrade paths, plus ablocks_jsonmap of material → count. - Saves happen on quit, on every successful sell, and on every upgrade purchase. The save uses an UPSERT (
UPDATE ... WHERE uuid=?with a fallbackINSERTif 0 rows updated) so a missing row never corrupts state. - On shutdown, all in-memory backpacks are flushed synchronously — even quit-during-save races don't lose blocks.
- The schema is created on enable with
SchemaBuilder; no manual migration is needed.
Optimal Token-Allocation Strategy
The right answer depends on your goal — but for most players, the priority order is:
- Capacity Lv 3 → 5. 160K–2.56M tokens total. Removes the "backpack full" interruption without breaking the bank.
- Autosell Lv 3 → 5. 200K–800K additional. A 19–75 second sell interval is enough for any mining loop.
- Multiplier Lv 5. 160K total for +5% on every sell. Pays back fast on high-value ores.
- Autosell Lv 10 (instant). 25.6M total — the long-term quality-of-life breakpoint. This is the "mining becomes pure block-breaking" upgrade.
- Multiplier Lv 10–20. 5M–5B total for +10–20%. Stack this once your pipeline multiplier is high enough that the +X% matters.
- Capacity Lv 10+. Only if you're mining AFK with mass-detonate abilities — the excess capacity prevents overflow during burst windows.
Don't chase Capacity past Lv 5–7 unless you're running mass-detonate builds. The doubling curve gives absurd headroom (Lv 5 = 3,200 blocks), and most mining sessions sell far more often than that.
Configurable Defaults
All four base costs and the capacity exponent are read from config.yml at plugin enable. If your server has tuned them, the numbers above change accordingly. The relevant keys:
| Config key | Default | Used for |
|---|---|---|
pouches.default_capacity | 100 | capacityBase in capacityAt() |
pouches.max_capacity_level | 60 | Upper bound on capacity level |
pouches.upgrade_cost_base | 10,000 | capacityCostBase in capacityCostAt() |
pouches.upgrade_cost_exponent | 2 | costExponent (1–4) |
pouches.autosell_cost_base | 50,000 | autosellCostBase in autosellCostAt() |
pouches.multiplier_cost_base | 10,000 | multiplierCostBase in multiplierCostAt() |
Quick Reference
| Setting | Value |
|---|---|
| Capacity formula | 100 × 2^level |
| Capacity cost | 10,000 × 2^(2×(level-1)), exp capped at 22 |
| Autosell interval | 5 min / 2^(level-1), instant at Lv 10 |
| Autosell cost | 50,000 × 2^(level-1), exp capped at 40 |
| Multiplier formula | 1 + level × 0.01 |
| Multiplier cost | 10,000 × 2^(level-1), exp capped at 40 |
| Sell tax | 5% → seasonal tax vault (rounded to cent) |
| Manual sell cooldown | 2 seconds per player (no autosell) |
| Mining summary cadence | Every 60 seconds (1,200 ticks) |
| Storage table | backpack_data (uuid PK + JSON blocks) |
| Manual sell command | /sellall |
| Upgrade currency | Auctoritas tokens (⛁) |