A persisted codec xmap whose lambdas call methods is read as plain linear arithmetic
Original description
By MelanX · October 24, 2026Crate: tools/minecraft-options
Commit: f844b107
Behavior
arithmetic_chain collects adjacent <const> <arith-op> pairs and skips every other instruction, including method calls. analyse_option_window resolves the persisted Codec.xmap through xmap_transform(dis, window[:idx], members, owner) with the default plain=False, so lambda_arithmetic never applies the is_plain_arithmetic guard on this path. A pair whose lambdas call Math.pow, Math.log10, Math.round or Mth helpers is accepted when invert_ops(encode) == decode on the linear remainder, and is reported with transform_resolved: true, a value_to_storage formula and transform_ops, although the real storage transform is non-linear.
The mouse wheel sensitivity slider pair (logMouse = Math.pow(10, i / 100.0), unlogMouse = round(log10(d) * 100)) resolves through xmap_transform as [* 100] in 1.19, 1.21.4 and 26.2 when plain is not set. Today that pair is a slider mapping, which slider_step already reads with plain=True, so no persisted transform in the bundled dataset is wrong.
Expected behavior
A codec xmap lambda containing any invocation other than boxing and unboxing (BOXING_CALLS) or any branch is left unresolved (xmap_unresolved), exactly like the slider path.
Impact
A release that moves such a pair onto the persisted codec would publish a wrong value_to_storage transform at high confidence.
Locations
tools/minecraft-options/analyze_options.pyanalyse_option_window(codecxmapbranch),xmap_transform,lambda_arithmetic,is_plain_arithmetic,arithmetic_chain
Validation and limitations
Read from the current code; the slider pair was checked against the cached 1.19, 1.21.4 and 26.2 JARs. A regression test can use a synthetic javap listing with the helpers in tools/minecraft-options/test_option_analysis.py.