FAILURE MAP
← Case archive

FA-86086 / Game economy crafting balance / Open access

Stamina regeneration: Overflow stamina is clamped back to cap · case 01

Potions that push stamina above cap are silently lost on the next update.

Verified by executionVariant 1 · 8 checks per implementationDownload source bundle ↓JSON ↗

ROOT CAUSE

The regeneration branch runs for overflow stamina and clamps it to cap.

THE FAILURE

The regeneration branch runs for overflow stamina and clamps it to cap.

Unsuccessful approach: Using the overflow ceiling as the regen limit also clamps overflow back to cap.

Case contract

Stamina regenerates 1 per 300 s while below cap, anchored at last_tick. Events [time, amount] are applied in time order (then amount); before each event (and finally at now) regeneration catches up: if it reaches cap the value becomes cap and the anchor moves to the event time, otherwise the anchor advances by whole periods. While at or above cap the anchor follows the event time. Amounts may push stamina above cap up to 999; negative amounts are spends that are rejected if they would go below zero. Return [stamina, anchor].

Why this case matters

Game economies leak or destroy currency when one crafting or pricing rule is off by one boundary, rounding stage or state update; the defect is observable in exact integer outcomes.

1 / The failure

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(stamina, cap, last_tick, now, refills):
    events = sorted(refills) + [[now, 0]]
    t = last_tick
    s = stamina
    for at, amount in events:
        if s != cap:
            gained = (at - t) // 300
            if s + gained >= cap:
                s = cap
                t = at
            else:
                s += gained
                t += gained * 300
        else:
            t = at
        if s + amount >= 0:
            s = min(999, s + amount)
    return [s, t]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
cases = [[('overflow potion persists #1', [5, 5, 0, 1200, [[100, 10]]], [15, 1200]),
  ('regression regen eligibility #1', [23, 20, 972, 1572, [[1185, -20], [1315, -20], [1066, 20]]], [3, 1315]),
  ('regression regen eligibility #2', [12, 13, 710, 1010, [[793, 7], [721, 13]]], [32, 1010]),
  ('regression regen eligibility #3', [11, 12, 57, 163, [[92, 12], [139, 12]]], [35, 163]),
  ('regression regen eligibility #4', [4, 13, 569, 868, [[776, 10]]], [14, 868]),
  ('exact refill to cap #1', [3, 5, 0, 600, []], [5, 600]),
  ('spend from full restarts timer #1', [10, 10, 0, 1000, [[400, -4]]], [8, 1000]),
  ('control #1', [9, 9, 266, 266, [[266, -9], [266, -10]]], [0, 266])],
 [('overflow potion persists #1', [5, 5, 0, 1200, [[100, 10]]], [15, 1200]),
  ('regression regen eligibility #1', [12, 13, 710, 1010, [[793, 7], [721, 13]]], [32, 1010]),
  ('regression regen eligibility #2', [11, 12, 57, 163, [[92, 12], [139, 12]]], [35, 163]),
  ('regression regen eligibility #3', [4, 13, 569, 868, [[776, 10]]], [14, 868]),
  ('regression regen eligibility #4', [0, 15, 688, 1288, [[1231, 15], [743, 9], [808, 15]]], [39, 1288]),
  ('exact refill to cap #1', [3, 5, 0, 600, []], [5, 600]),
  ('spend from full restarts timer #1', [10, 10, 0, 1000, [[400, -4]]], [8, 1000]),
  ('control #1', [9, 9, 266, 266, [[266, -9], [266, -10]]], [0, 266])],
 [('overflow potion persists #1', [5, 5, 0, 1200, [[100, 10]]], [15, 1200]),
  ('regression regen eligibility #1', [4, 13, 569, 868, [[776, 10]]], [14, 868]),
  ('regression regen eligibility #2', [0, 15, 688, 1288, [[1231, 15], [743, 9], [808, 15]]], [39, 1288]),
  ('regression regen eligibility #3', [0, 7, 587, 587, [[587, 8], [587, 9]]], [17, 587]),
  ('regression regen eligibility #4', [17, 17, 382, 982, [[483, 17], [862, -6], [923, 17]]], [45, 982]),
  ('exact refill to cap #1', [3, 5, 0, 600, []], [5, 600]),
  ('spend from full restarts timer #1', [10, 10, 0, 1000, [[400, -4]]], [8, 1000]),
  ('control #1', [9, 9, 266, 266, [[266, -9], [266, -10]]], [0, 266])],
 [('overflow potion persists #1', [5, 5, 0, 1200, [[100, 10]]], [15, 1200]),
  ('regression regen eligibility #1', [0, 7, 587, 587, [[587, 8], [587, 9]]], [17, 587]),
  ('regression regen eligibility #2', [17, 17, 382, 982, [[483, 17], [862, -6], [923, 17]]], [45, 982]),
  ('regression regen eligibility #3', [4, 11, 767, 2462, [[2177, 7], [1959, -11], [1673, 11]]], [14, 2462]),
  ('regression regen eligibility #4', [20, 17, 920, 1520, [[1180, -17], [1013, -17], [1246, -5]]], [4, 1313]),
  ('exact refill to cap #1', [3, 5, 0, 600, []], [5, 600]),
  ('spend from full restarts timer #1', [10, 10, 0, 1000, [[400, -4]]], [8, 1000]),
  ('control #1', [16, 17, 83, 1773, [[154, -6]]], [15, 1583])],
 [('overflow potion persists #1', [5, 5, 0, 1200, [[100, 10]]], [15, 1200]),
  ('regression regen eligibility #1', [4, 11, 767, 2462, [[2177, 7], [1959, -11], [1673, 11]]], [14, 2462]),
  ('regression regen eligibility #2', [20, 17, 920, 1520, [[1180, -17], [1013, -17], [1246, -5]]], [4, 1313]),
  ('regression regen eligibility #3', [12, 12, 443, 1043, [[843, 12]]], [24, 1043]),
  ('regression regen eligibility #4', [17, 14, 635, 1235, [[995, 11], [1111, 14]]], [42, 1235]),
  ('exact refill to cap #1', [3, 5, 0, 600, []], [5, 600]),
  ('spend from full restarts timer #1', [10, 10, 0, 1000, [[400, -4]]], [8, 1000]),
  ('control #1', [17, 18, 353, 353, []], [17, 353])]]
for label, args, expected in cases[N-1]:
    check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
overflow potion persists #1[5, 1200][15, 1200]Failed
regression regen eligibility #1[1, 1485][3, 1315]Failed
regression regen eligibility #2[13, 1010][32, 1010]Failed
regression regen eligibility #3[12, 163][35, 163]Failed
regression regen eligibility #4[13, 868][14, 868]Failed
exact refill to cap #1[5, 600][5, 600]Passed
spend from full restarts timer #1[8, 1000][8, 1000]Passed
control #1[0, 266][0, 266]Passed

SHA-256 / a3f0a02d9e4e2f575a7b244d3982ece397058579046fca6584d3ae76e0e0a0d4

2 / The unsuccessful fix

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(stamina, cap, last_tick, now, refills):
    events = sorted(refills) + [[now, 0]]
    t = last_tick
    s = stamina
    for at, amount in events:
        if s < 999:
            gained = (at - t) // 300
            if s + gained >= cap:
                s = cap
                t = at
            else:
                s += gained
                t += gained * 300
        else:
            t = at
        if s + amount >= 0:
            s = min(999, s + amount)
    return [s, t]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
cases = [[('overflow potion persists #1', [5, 5, 0, 1200, [[100, 10]]], [15, 1200]),
  ('regression regen eligibility #1', [23, 20, 972, 1572, [[1185, -20], [1315, -20], [1066, 20]]], [3, 1315]),
  ('regression regen eligibility #2', [12, 13, 710, 1010, [[793, 7], [721, 13]]], [32, 1010]),
  ('regression regen eligibility #3', [11, 12, 57, 163, [[92, 12], [139, 12]]], [35, 163]),
  ('regression regen eligibility #4', [4, 13, 569, 868, [[776, 10]]], [14, 868]),
  ('exact refill to cap #1', [3, 5, 0, 600, []], [5, 600]),
  ('spend from full restarts timer #1', [10, 10, 0, 1000, [[400, -4]]], [8, 1000]),
  ('control #1', [9, 9, 266, 266, [[266, -9], [266, -10]]], [0, 266])],
 [('overflow potion persists #1', [5, 5, 0, 1200, [[100, 10]]], [15, 1200]),
  ('regression regen eligibility #1', [12, 13, 710, 1010, [[793, 7], [721, 13]]], [32, 1010]),
  ('regression regen eligibility #2', [11, 12, 57, 163, [[92, 12], [139, 12]]], [35, 163]),
  ('regression regen eligibility #3', [4, 13, 569, 868, [[776, 10]]], [14, 868]),
  ('regression regen eligibility #4', [0, 15, 688, 1288, [[1231, 15], [743, 9], [808, 15]]], [39, 1288]),
  ('exact refill to cap #1', [3, 5, 0, 600, []], [5, 600]),
  ('spend from full restarts timer #1', [10, 10, 0, 1000, [[400, -4]]], [8, 1000]),
  ('control #1', [9, 9, 266, 266, [[266, -9], [266, -10]]], [0, 266])],
 [('overflow potion persists #1', [5, 5, 0, 1200, [[100, 10]]], [15, 1200]),
  ('regression regen eligibility #1', [4, 13, 569, 868, [[776, 10]]], [14, 868]),
  ('regression regen eligibility #2', [0, 15, 688, 1288, [[1231, 15], [743, 9], [808, 15]]], [39, 1288]),
  ('regression regen eligibility #3', [0, 7, 587, 587, [[587, 8], [587, 9]]], [17, 587]),
  ('regression regen eligibility #4', [17, 17, 382, 982, [[483, 17], [862, -6], [923, 17]]], [45, 982]),
  ('exact refill to cap #1', [3, 5, 0, 600, []], [5, 600]),
  ('spend from full restarts timer #1', [10, 10, 0, 1000, [[400, -4]]], [8, 1000]),
  ('control #1', [9, 9, 266, 266, [[266, -9], [266, -10]]], [0, 266])],
 [('overflow potion persists #1', [5, 5, 0, 1200, [[100, 10]]], [15, 1200]),
  ('regression regen eligibility #1', [0, 7, 587, 587, [[587, 8], [587, 9]]], [17, 587]),
  ('regression regen eligibility #2', [17, 17, 382, 982, [[483, 17], [862, -6], [923, 17]]], [45, 982]),
  ('regression regen eligibility #3', [4, 11, 767, 2462, [[2177, 7], [1959, -11], [1673, 11]]], [14, 2462]),
  ('regression regen eligibility #4', [20, 17, 920, 1520, [[1180, -17], [1013, -17], [1246, -5]]], [4, 1313]),
  ('exact refill to cap #1', [3, 5, 0, 600, []], [5, 600]),
  ('spend from full restarts timer #1', [10, 10, 0, 1000, [[400, -4]]], [8, 1000]),
  ('control #1', [16, 17, 83, 1773, [[154, -6]]], [15, 1583])],
 [('overflow potion persists #1', [5, 5, 0, 1200, [[100, 10]]], [15, 1200]),
  ('regression regen eligibility #1', [4, 11, 767, 2462, [[2177, 7], [1959, -11], [1673, 11]]], [14, 2462]),
  ('regression regen eligibility #2', [20, 17, 920, 1520, [[1180, -17], [1013, -17], [1246, -5]]], [4, 1313]),
  ('regression regen eligibility #3', [12, 12, 443, 1043, [[843, 12]]], [24, 1043]),
  ('regression regen eligibility #4', [17, 14, 635, 1235, [[995, 11], [1111, 14]]], [42, 1235]),
  ('exact refill to cap #1', [3, 5, 0, 600, []], [5, 600]),
  ('spend from full restarts timer #1', [10, 10, 0, 1000, [[400, -4]]], [8, 1000]),
  ('control #1', [17, 18, 353, 353, []], [17, 353])]]
for label, args, expected in cases[N-1]:
    check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
overflow potion persists #1[5, 1200][15, 1200]Failed
regression regen eligibility #1[1, 1485][3, 1315]Failed
regression regen eligibility #2[13, 1010][32, 1010]Failed
regression regen eligibility #3[12, 163][35, 163]Failed
regression regen eligibility #4[13, 868][14, 868]Failed
exact refill to cap #1[5, 600][5, 600]Passed
spend from full restarts timer #1[8, 1000][8, 1000]Passed
control #1[0, 266][0, 266]Passed

SHA-256 / 4ab2d2964ebfda9d20b570c17c1104012e8c2670e884cfa2a9b6b1b382a20c50

HELD IN THE MEMBER ARCHIVE

The verified repair and its recorded checks are member-only.

This mechanism has 8 recorded checks per implementation. The open-access tier publishes the failure and the unsuccessful fix; the repaired source that passes every check, and the observations that prove it, are available to members.

Every case sharing this mechanism uses the same contract and the same repair, so this one record is held back for all of them.

Member access is invitation-based. Sign in with your invited account to inspect the repair.

Sign in to the archive ↗

Verification & scope

Deterministic toy contract stipulated for this model; integer or exact arithmetic only, not a reproduction of any specific game engine. This reproducer isolates one failure mechanism. Results cover the supplied fixtures. Variants within a family share a test contract and should remain grouped when constructing evaluation splits. Related mechanisms with a shared evaluation_group must also remain together; these controlled models are not independent production incidents.

Observations recorded using Python 3.12.14 at 2026-09-29T14:50:46.314504+00:00.

Case digest / 561ddb5e550db6b8e6292572752a087f63107b56e5ea4aa115182829618388b5