Skip to content

fix(theme): centre the nudge that recovers the screen size - #25

Merged
lusu007 merged 1 commit into
mainfrom
feat/gui-scale
Aug 11, 2026
Merged

fix(theme): centre the nudge that recovers the screen size#25
lusu007 merged 1 commit into
mainfrom
feat/gui-scale

Conversation

@hbrombeer

Copy link
Copy Markdown
Member

Every marker sits at floor(screen / 2) + offset, and screen is recovered from the projection matrix rather than known. Wrong by one, and every themed screen is a pixel out at some resolutions and fine at others — found by a player, not by us. This was the one Phase 2 item from the architecture plan still untouched.

The bound is two-sided, which is what makes the value non-obvious:

  • a round trip that comes back high needs the nudge to exceed the error, or the ceiling jumps a whole pixel;
  • one that comes back low needs it to stay a pixel clear of 1.0, or a real width is rounded away.

Safe range is [error, 1 - error]; the value that survives the widest displays is the middle of it.

It was 0.001 — legal, but against the floor. Measured, the error peaks at 4.9e-4 near width 5837 and grows with width, so it held a factor of two and would have failed on a display twice as wide. 0.5 holds a factor of a thousand and costs nothing.

This came out of failing to falsify the test. Perturbing the nudge to 0.5 did not break it, because 0.5 was also correct — which a one-sided assertion could not tell me. Both ends are asserted now; 0.0001 and 0.999 each break it.

Checked without a GPU because this is the one part of a shader that is not GPU-specific: GLSL highp float and JVM Float are both binary32. The recovery is replayed over every width 1..8192, and the epsilon is read out of the shipped shader so a change there cannot pass by being invisible to the test.

143 tests, 0 failures.

Every marker sits at floor(screen / 2) + offset, and screen is not known but
recovered: the shader divides 2 by the projection matrix's first term and
takes a ceiling, minus a nudge for the round trip through float. Get that
nudge wrong and every themed screen is a pixel out at some resolutions and
correct at others, which is a bug found by a player rather than by us.

The bound turns out to be two-sided, and that is what makes the value
non-obvious. A round trip that comes back high needs the nudge to exceed the
error, or the ceiling jumps a whole pixel. One that comes back low needs the
nudge to stay a pixel clear of 1.0, or a real width is rounded away. So the
safe range is [error, 1 - error], and the value that survives the widest
displays is the middle of it.

It was 0.001. Legal, but sitting against the floor: the measured error peaks
at 4.9e-4 near width 5837 and grows with the width, so it held a factor of
two and would have failed on a display twice as wide. Half holds a factor of
a thousand and costs nothing.

This came out of trying to falsify the new test. Perturbing the nudge to 0.5
did not make it fail — because 0.5 was also correct, which is what a
one-sided assertion could not tell me. The test asserts both ends now, and
0.0001 and 0.999 each break it.

The arithmetic is checked without a GPU because it is the one part of a
shader that is not GPU-specific: GLSL's highp float and the JVM's Float are
both binary32, so the recovery is replayed over every width the client can
produce, and the epsilon is read out of the shipped shader rather than
repeated so a change there cannot pass by being invisible.
@lusu007
lusu007 merged commit f2961c3 into main Aug 11, 2026
2 checks passed
@lusu007
lusu007 deleted the feat/gui-scale branch August 11, 2026 08:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants