Skip to content

Major launcher Improvements

Choose a tag to compare

@ChimeraAnt-DEV ChimeraAnt-DEV released this 15 Sep 22:05
· 230 commits to main since this release
6c99565
  1. Touch reactivity — two real bugs, not just new animation

applyPressScale was silently destroying other touch listeners. It called a bare setOnTouchListener. ModsAdapter had installed a drag-handle listener that begins an ItemTouchHelper drag on ACTION_DOWN, then asked for press feedback on the same view. The feedback call replaced that listener, so drag-to-reorder was broken with no error and no crash — it just stopped responding. Added a delegate overload; the delegate runs after the press effect and its return value is honoured. Confirmed no other call site in the tree attaches both (57 applyPressScale call sites audited).

Press animation was being cut off at the start. setStartVelocity was called after animateToFinalPosition, which begins the animation immediately, so the velocity was discarded and every press eased in from a standstill. Now set before starting. Springs are also built once per view and cached in a view tag (R.id.dynamic_anim_press_state, new res/values/ids.xml) instead of allocating four objects per touch event, and are re-targeted rather than rebuilt.

Presses that turn into a scroll snap back to full size past touch slop, so rows don't stay shrunk while flinging.

Known caveat, documented: a press state cached on a recycled view carries a delegate closed over the previous holder. It's currently safe because the delegate resolves the holder at call time via itemTouchHelper, but that's fragile — noted in AGENTS.md so it gets re-checked if a rebound delegate ever captures the holder directly.
2. Launcher UI — the text clipping was a real bug, in 45 more places

The home-screen cut-off text was one instance of a general defect: text-bearing buttons pinned android:layout_height to a hardcoded dp value. A fixed height does not grow with the user's font scale, so labels clip at any accessibility text size.

Converted 45 text-bearing buttons across 20 layouts to wrap_content + android:minHeight (original dp preserved as the minimum, so the default-scale appearance is unchanged).

Only views carrying android:text were touched. The remaining fixed heights are icon-only touch targets where a fixed square is correct and wrap_content would collapse them. All XML re-validated as parseable.
3. Low Input Delay — was paying a lock on every input event

ControllerInputProcessor read path was synchronized, and it runs on the UI thread inside MinecraftActivity.dispatchKeyEvent / dispatchGenericMotionEvent. Every controller event paid for a monitor enter/exit before the game saw it, and because the old code locked per-method rather than per-read, a profile swap from the UI thread could be observed mid-event.

Now the active state is a single immutable volatile ControllerResponse:

Readers take no lock and cannot see a half-applied profile.
Dead-zone division folded into a multiply.
Stick remaps are a flat int[] indexed by key code, not a HashMap lookup.
Response curve is a polynomial, not Math.pow.

The toggle now also tightens the dead zone and applies an ease-out curve, so the same physical stick travel produces more look output — a measurable change rather than a relabel. Applied via reload() so it takes effect without restarting the session.

Also fixed: isWithinDeadZone returning true for an all-zero event swallows controller button presses, which also arrive through dispatchGenericMotionEvent.

18 unit tests (ControllerResponseTest, no mocks) cover dead-zone boundaries, monotonicity, sign, clamping, drift snapping, the remap table and null-profile fallback. Verified by mutation — disabling the curve or the sign handling fails them.
4. Reduce Network Latency

Socket buffers were 256 KiB, which is backwards for request/response traffic and lets the stack hold back small writes. Now 64 KiB.
Warm ConnectionPool(8, 5min) so TCP+TLS handshakes are already done on the next request.
DNS prefetch and the game-session quiet zone retained.
Deliberately does not override connect/read timeouts — each caller sets its own (CurseForgeClient 30s, PreloaderSignatureRulesManager 10s).
  1. 32-bit instances — cannot be done, and I did not pretend otherwise

The request was to run 32-bit instances from a 64-bit launcher. This is not achievable from inside the app, and nothing shipped claims otherwise.

Android fixes a process's bitness at install time from the app's own native libs. This APK ships arm64-v8a only, so the process is 64-bit.
32-bit libraries cannot dlopen in a 64-bit process. Confirmed against Android NDK docs.
android:use32bitAbi does not help. It only tells the installer to prefer 32-bit libs an app already ships — a packaging choice, not a runtime switch. There is no API to run part of an app 32-bit and part 64-bit.
Since MinecraftActivity runs in-process, a separate-process workaround is not available either.
Real support requires shipping armeabi-v7a natives (including the prebuilt libgxcore.so, which is arm64-only by design) as a second APK.

What shipped instead is a clear, actionable preflight message. GamePackageManager.abiCompatibility() now returns an explicit result and abiMismatchMessage() distinguishes "your device supports 32-bit, you need a 32-bit launcher build" from "this device is 64-bit only". This replaces a confusing mid-launch dlopen failed: is 32-bit instead of 64-bit.

Not shipped: "10–0 ping". A launcher cannot move a game server closer, change ISP routing, or make a third-party server reply sooner. What it removes is latency the device itself adds — Nagle, delayed-ACK, buffer bloat, cold DNS, redundant handshakes. That's real (often tens of ms on request/response) but it is not the ping number the user sees. Both toggle strings now describe what the code actually does, including what it cannot do: "Cannot change the distance to a game server or its own response time."
6. Aim Settings

Built per the earlier request as the renamed Hit Registration module. Kept honestly scoped: Bedrock hit registration is server-authoritative, so a client-side module cannot improve it. What it genuinely tunes is look-delta quality. I did not add anything that claims to fix registration it cannot touch. If you'd rather it be labelled differently, that's a quick change.
Verification
Check Result
:app:testDebugUnitTest 65 tests, 0 failures (18 new)
:app:compileDebugKotlin / JavaWithJavac pass
:app:assembleDebug BUILD SUCCESSFUL, APK produced
XML validity (all layouts/drawables/values) 0 invalid files
Mutation check on new tests regression correctly fails

Working tree clean. No new external dependencies. Only warning is the pre-existing Gradle 9.0 deprecation notice.