FA-86331 / Game economy crafting balance / Open access
Crafting XP with rested pool: Capped characters keep leftover xp · case 01
The xp bar shows progress past the level cap.
ROOT CAUSE
Reaching the cap leaves the carried xp on the bar.
VERIFIED REPAIR
Restore `if level >= 50: xp = 0` at the cap bar reset step.
Unsuccessful approach: Clamping to the requirement still shows a non-empty bar at cap.
Case contract
Level L needs 80 + 20*L xp to reach L+1; max level 50. Gains are ignored once level 50 is reached (rested untouched). For each gain g: bonus = min(g, rested) is added on top of g and removed from the rested pool; then as many levels as possible are taken, carrying remaining xp; on reaching level 50 the xp bar is set to 0. Returns [level, xp, rested].
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(level, xp, gains, rested):
for g in gains:
if level >= 50:
break
bonus = min(g, rested)
rested -= bonus
xp += g + bonus
while level < 50 and xp >= 80 + 20 * level:
xp -= 80 + 20 * level
level += 1
if level >= 50:
pass
return [level, xp, rested]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
cases = [[('regression cap bar reset #1', [49, 56, [516, 2000], 100], [50, 0, 0]),
('regression cap bar reset #2', [49, 57, [300, 2000, 274], 0], [50, 0, 0]),
('regression cap bar reset #3', [49, 101, [300, 300, 100, 99, 100], 1000], [50, 0, 400]),
('regression cap bar reset #4', [49, 62, [99, 10, 2000, 99], 0], [50, 0, 0]),
('multi-level gain #1', [1, 0, [300], 0], [3, 80, 0]),
('exact threshold #1', [10, 0, [280], 0], [11, 0, 0]),
('gain at cap keeps rested #1', [50, 0, [100], 40], [50, 0, 40]),
('control #1', [48, 123, [50, 10, 420], 100], [48, 703, 0])],
[('regression cap bar reset #1', [49, 101, [300, 300, 100, 99, 100], 1000], [50, 0, 400]),
('regression cap bar reset #2', [49, 62, [99, 10, 2000, 99], 0], [50, 0, 0]),
('regression cap bar reset #3', [49, 90, [2000, 89], 100], [50, 0, 0]),
('regression cap bar reset #4', [49, 126, [2000, 99], 345], [50, 0, 0]),
('gain at cap keeps rested #1', [50, 0, [100], 40], [50, 0, 40]),
('multi-level gain #1', [1, 0, [300], 0], [3, 80, 0]),
('control #1', [48, 123, [50, 10, 420], 100], [48, 703, 0]),
('control #2', [50, 56, [99], 100], [50, 56, 100])],
[('regression cap bar reset #1', [49, 90, [2000, 89], 100], [50, 0, 0]),
('regression cap bar reset #2', [49, 126, [2000, 99], 345], [50, 0, 0]),
('regression cap bar reset #3', [49, 62, [300, 393, 300, 300], 0], [50, 0, 0]),
('regression cap bar reset #4', [49, 50, [2000, 50], 1000], [50, 0, 0]),
('exact threshold #1', [10, 0, [280], 0], [11, 0, 0]),
('gain at cap keeps rested #1', [50, 0, [100], 40], [50, 0, 40]),
('control #1', [50, 56, [99], 100], [50, 56, 100]),
('control #2', [5, 79, [300], 0], [6, 199, 0])],
[('regression cap bar reset #1', [49, 62, [300, 393, 300, 300], 0], [50, 0, 0]),
('regression cap bar reset #2', [49, 50, [2000, 50], 1000], [50, 0, 0]),
('regression cap bar reset #3', [49, 47, [100, 10, 2000, 99], 100], [50, 0, 0]),
('regression cap bar reset #4', [49, 132, [300, 50, 99, 99], 1000], [50, 0, 452]),
('multi-level gain #1', [1, 0, [300], 0], [3, 80, 0]),
('exact threshold #1', [10, 0, [280], 0], [11, 0, 0]),
('control #1', [10, 7, [300, 50, 99, 100], 0], [11, 276, 0]),
('control #2', [48, 108, [300, 300, 99, 86, 300], 30], [49, 183, 0])],
[('regression cap bar reset #1', [49, 47, [100, 10, 2000, 99], 100], [50, 0, 0]),
('regression cap bar reset #2', [49, 132, [300, 50, 99, 99], 1000], [50, 0, 452]),
('regression cap bar reset #3', [49, 30, [2000, 2000, 99, 10], 16], [50, 0, 0]),
('regression cap bar reset #4', [49, 105, [300, 300, 10, 390, 100], 0], [50, 0, 0]),
('gain at cap keeps rested #1', [50, 0, [100], 40], [50, 0, 40]),
('multi-level gain #1', [1, 0, [300], 0], [3, 80, 0]),
('control #1', [5, 79, [100, 10, 2000], 0], [13, 189, 0]),
('control #2', [29, 125, [2000], 0], [32, 85, 0])]]
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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| regression cap bar reset #1 | [50, 1612, 0] | [50, 0, 0] | Failed |
| regression cap bar reset #2 | [50, 1297, 0] | [50, 0, 0] | Failed |
| regression cap bar reset #3 | [50, 241, 400] | [50, 0, 400] | Failed |
| regression cap bar reset #4 | [50, 1111, 0] | [50, 0, 0] | Failed |
| multi-level gain #1 | [3, 80, 0] | [3, 80, 0] | Passed |
| exact threshold #1 | [11, 0, 0] | [11, 0, 0] | Passed |
| gain at cap keeps rested #1 | [50, 0, 40] | [50, 0, 40] | Passed |
| control #1 | [48, 703, 0] | [48, 703, 0] | Passed |
SHA-256 / 5dbaaeddf2eb052b9426af796ec3cea61c00eddf822c653784511e5e75fcbdc5
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(level, xp, gains, rested):
for g in gains:
if level >= 50:
break
bonus = min(g, rested)
rested -= bonus
xp += g + bonus
while level < 50 and xp >= 80 + 20 * level:
xp -= 80 + 20 * level
level += 1
if level >= 50:
xp = min(xp, 80 + 20 * level)
return [level, xp, rested]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
cases = [[('regression cap bar reset #1', [49, 56, [516, 2000], 100], [50, 0, 0]),
('regression cap bar reset #2', [49, 57, [300, 2000, 274], 0], [50, 0, 0]),
('regression cap bar reset #3', [49, 101, [300, 300, 100, 99, 100], 1000], [50, 0, 400]),
('regression cap bar reset #4', [49, 62, [99, 10, 2000, 99], 0], [50, 0, 0]),
('multi-level gain #1', [1, 0, [300], 0], [3, 80, 0]),
('exact threshold #1', [10, 0, [280], 0], [11, 0, 0]),
('gain at cap keeps rested #1', [50, 0, [100], 40], [50, 0, 40]),
('control #1', [48, 123, [50, 10, 420], 100], [48, 703, 0])],
[('regression cap bar reset #1', [49, 101, [300, 300, 100, 99, 100], 1000], [50, 0, 400]),
('regression cap bar reset #2', [49, 62, [99, 10, 2000, 99], 0], [50, 0, 0]),
('regression cap bar reset #3', [49, 90, [2000, 89], 100], [50, 0, 0]),
('regression cap bar reset #4', [49, 126, [2000, 99], 345], [50, 0, 0]),
('gain at cap keeps rested #1', [50, 0, [100], 40], [50, 0, 40]),
('multi-level gain #1', [1, 0, [300], 0], [3, 80, 0]),
('control #1', [48, 123, [50, 10, 420], 100], [48, 703, 0]),
('control #2', [50, 56, [99], 100], [50, 56, 100])],
[('regression cap bar reset #1', [49, 90, [2000, 89], 100], [50, 0, 0]),
('regression cap bar reset #2', [49, 126, [2000, 99], 345], [50, 0, 0]),
('regression cap bar reset #3', [49, 62, [300, 393, 300, 300], 0], [50, 0, 0]),
('regression cap bar reset #4', [49, 50, [2000, 50], 1000], [50, 0, 0]),
('exact threshold #1', [10, 0, [280], 0], [11, 0, 0]),
('gain at cap keeps rested #1', [50, 0, [100], 40], [50, 0, 40]),
('control #1', [50, 56, [99], 100], [50, 56, 100]),
('control #2', [5, 79, [300], 0], [6, 199, 0])],
[('regression cap bar reset #1', [49, 62, [300, 393, 300, 300], 0], [50, 0, 0]),
('regression cap bar reset #2', [49, 50, [2000, 50], 1000], [50, 0, 0]),
('regression cap bar reset #3', [49, 47, [100, 10, 2000, 99], 100], [50, 0, 0]),
('regression cap bar reset #4', [49, 132, [300, 50, 99, 99], 1000], [50, 0, 452]),
('multi-level gain #1', [1, 0, [300], 0], [3, 80, 0]),
('exact threshold #1', [10, 0, [280], 0], [11, 0, 0]),
('control #1', [10, 7, [300, 50, 99, 100], 0], [11, 276, 0]),
('control #2', [48, 108, [300, 300, 99, 86, 300], 30], [49, 183, 0])],
[('regression cap bar reset #1', [49, 47, [100, 10, 2000, 99], 100], [50, 0, 0]),
('regression cap bar reset #2', [49, 132, [300, 50, 99, 99], 1000], [50, 0, 452]),
('regression cap bar reset #3', [49, 30, [2000, 2000, 99, 10], 16], [50, 0, 0]),
('regression cap bar reset #4', [49, 105, [300, 300, 10, 390, 100], 0], [50, 0, 0]),
('gain at cap keeps rested #1', [50, 0, [100], 40], [50, 0, 40]),
('multi-level gain #1', [1, 0, [300], 0], [3, 80, 0]),
('control #1', [5, 79, [100, 10, 2000], 0], [13, 189, 0]),
('control #2', [29, 125, [2000], 0], [32, 85, 0])]]
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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| regression cap bar reset #1 | [50, 1080, 0] | [50, 0, 0] | Failed |
| regression cap bar reset #2 | [50, 1080, 0] | [50, 0, 0] | Failed |
| regression cap bar reset #3 | [50, 241, 400] | [50, 0, 400] | Failed |
| regression cap bar reset #4 | [50, 1080, 0] | [50, 0, 0] | Failed |
| multi-level gain #1 | [3, 80, 0] | [3, 80, 0] | Passed |
| exact threshold #1 | [11, 0, 0] | [11, 0, 0] | Passed |
| gain at cap keeps rested #1 | [50, 0, 40] | [50, 0, 40] | Passed |
| control #1 | [48, 703, 0] | [48, 703, 0] | Passed |
SHA-256 / 15786f8217c2062451cbb3247defc64e133bbe451f9212820360d095286643a0
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(level, xp, gains, rested):
for g in gains:
if level >= 50:
break
bonus = min(g, rested)
rested -= bonus
xp += g + bonus
while level < 50 and xp >= 80 + 20 * level:
xp -= 80 + 20 * level
level += 1
if level >= 50:
xp = 0
return [level, xp, rested]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
cases = [[('regression cap bar reset #1', [49, 56, [516, 2000], 100], [50, 0, 0]),
('regression cap bar reset #2', [49, 57, [300, 2000, 274], 0], [50, 0, 0]),
('regression cap bar reset #3', [49, 101, [300, 300, 100, 99, 100], 1000], [50, 0, 400]),
('regression cap bar reset #4', [49, 62, [99, 10, 2000, 99], 0], [50, 0, 0]),
('multi-level gain #1', [1, 0, [300], 0], [3, 80, 0]),
('exact threshold #1', [10, 0, [280], 0], [11, 0, 0]),
('gain at cap keeps rested #1', [50, 0, [100], 40], [50, 0, 40]),
('control #1', [48, 123, [50, 10, 420], 100], [48, 703, 0])],
[('regression cap bar reset #1', [49, 101, [300, 300, 100, 99, 100], 1000], [50, 0, 400]),
('regression cap bar reset #2', [49, 62, [99, 10, 2000, 99], 0], [50, 0, 0]),
('regression cap bar reset #3', [49, 90, [2000, 89], 100], [50, 0, 0]),
('regression cap bar reset #4', [49, 126, [2000, 99], 345], [50, 0, 0]),
('gain at cap keeps rested #1', [50, 0, [100], 40], [50, 0, 40]),
('multi-level gain #1', [1, 0, [300], 0], [3, 80, 0]),
('control #1', [48, 123, [50, 10, 420], 100], [48, 703, 0]),
('control #2', [50, 56, [99], 100], [50, 56, 100])],
[('regression cap bar reset #1', [49, 90, [2000, 89], 100], [50, 0, 0]),
('regression cap bar reset #2', [49, 126, [2000, 99], 345], [50, 0, 0]),
('regression cap bar reset #3', [49, 62, [300, 393, 300, 300], 0], [50, 0, 0]),
('regression cap bar reset #4', [49, 50, [2000, 50], 1000], [50, 0, 0]),
('exact threshold #1', [10, 0, [280], 0], [11, 0, 0]),
('gain at cap keeps rested #1', [50, 0, [100], 40], [50, 0, 40]),
('control #1', [50, 56, [99], 100], [50, 56, 100]),
('control #2', [5, 79, [300], 0], [6, 199, 0])],
[('regression cap bar reset #1', [49, 62, [300, 393, 300, 300], 0], [50, 0, 0]),
('regression cap bar reset #2', [49, 50, [2000, 50], 1000], [50, 0, 0]),
('regression cap bar reset #3', [49, 47, [100, 10, 2000, 99], 100], [50, 0, 0]),
('regression cap bar reset #4', [49, 132, [300, 50, 99, 99], 1000], [50, 0, 452]),
('multi-level gain #1', [1, 0, [300], 0], [3, 80, 0]),
('exact threshold #1', [10, 0, [280], 0], [11, 0, 0]),
('control #1', [10, 7, [300, 50, 99, 100], 0], [11, 276, 0]),
('control #2', [48, 108, [300, 300, 99, 86, 300], 30], [49, 183, 0])],
[('regression cap bar reset #1', [49, 47, [100, 10, 2000, 99], 100], [50, 0, 0]),
('regression cap bar reset #2', [49, 132, [300, 50, 99, 99], 1000], [50, 0, 452]),
('regression cap bar reset #3', [49, 30, [2000, 2000, 99, 10], 16], [50, 0, 0]),
('regression cap bar reset #4', [49, 105, [300, 300, 10, 390, 100], 0], [50, 0, 0]),
('gain at cap keeps rested #1', [50, 0, [100], 40], [50, 0, 40]),
('multi-level gain #1', [1, 0, [300], 0], [3, 80, 0]),
('control #1', [5, 79, [100, 10, 2000], 0], [13, 189, 0]),
('control #2', [29, 125, [2000], 0], [32, 85, 0])]]
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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| regression cap bar reset #1 | [50, 0, 0] | [50, 0, 0] | Passed |
| regression cap bar reset #2 | [50, 0, 0] | [50, 0, 0] | Passed |
| regression cap bar reset #3 | [50, 0, 400] | [50, 0, 400] | Passed |
| regression cap bar reset #4 | [50, 0, 0] | [50, 0, 0] | Passed |
| multi-level gain #1 | [3, 80, 0] | [3, 80, 0] | Passed |
| exact threshold #1 | [11, 0, 0] | [11, 0, 0] | Passed |
| gain at cap keeps rested #1 | [50, 0, 40] | [50, 0, 40] | Passed |
| control #1 | [48, 703, 0] | [48, 703, 0] | Passed |
SHA-256 / f2b6015cf1742ff0fd2b0f62d0e19e679e8995feb1647bc4908bb7ad86f36274
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:48.615101+00:00.
Case digest / 065a37daa0a14ecb470a5c704b7c15bbef8a52945b86d1afe7186408616bf421