Skip to content

Releases: ChimeraAnt-DEV/GlowberryClient

OFFICIAL FIRST RELEASE

Choose a tag to compare

@ChimeraAnt-DEV ChimeraAnt-DEV released this 02 Oct 15:19
76e00ed

Context Confirmed

  • Repo: ChimeraAnt-DEV/GlowberryClient (slug is still GlowberryClient; docs/URLs still point at the old ChimeraLauncher slug).
  • V7 tag = merge commit of PR #72 ("mcpe-planet source + Hitboxes/Select Hit"), tagged 2026-09-25.
  • The "copied PR description" is the BETA release ("Biggest update so far…", 2026-09-27). Its body is the PR #78 description verbatim (.AntEgg + proximity voice + in-game pack changer + cape/overlay fixes), including the "created by Malice" sign-off.
  • Since V7: 91 commits, 486 files changed, +47,801 / −1,529, and 24 merged PRs (#73–#95).
  • Font angle is real, not a red herring: the repo actually ships a bundled font catalogue — LauncherFonts.java + 29 TTFs in app/src/main/res/font/ — added in commit 86eefbd (part of PR #89), which is after V7. So "fonts since V7" is a genuine change too.

Part 1 — What changed since the V7 release

Everything below landed after tag V7 (PR #72). The BETA release is PR #78; PRs #79–#95 came after it.

1. Rebrand & identity

  • Chimera Client → GlowberryClient (PR #86): app name, ~11 locale strings, OAuth user agents, backup folder, voice join-code prefix CHIMERA- → GLOWBERRY-, docs/release/news JSON. Java package stays org.chimeramc.* deliberately.
  • New launcher icon (PR #87): golden glowberry on a dark-purple gradient tile, full-bleed adaptive + themed (mono) icon, recoloured adaptive background.
  • README/docs refresh (PRs #84, #85): removed fork lineage, added rights/shared-account footer; EN + zh-CN docs site updated.

2. Proximity voice chat (the biggest new subsystem)

  • PR #78 — LAN-multicast voice between Chimera users in the same world, raw 16 kHz PCM, mic capture + RECORD_AUDIO.
  • PR #79 — voice channels: public/private, shareable join codes (GLOWBERRY-XXXX), live client-side directory, dedicated Voice tab, pixel-art mic meter. Protocol v2.
  • PR #82 — per-channel controls, advisory capacity, viewer-only per-member mute, in-world nametag mic icon; protocol v3.
  • PR #83 — real local-player feed (position + view rotation via ClientInstance vtable slot 31) so the nametag icon actually renders.
  • PR #88 — internet voice: a standalone Go UDP relay server (server/voice-relay), Opus codec, jitter buffer, mixer, relay address setting, token auth + bans, Docker/systemd/Fly.io deploy; protocol v4; proximity distance rule fixed.

3. Mod packaging & porting

  • PR #78 — .AntEgg format: ZIP container, egg.json manifest, native or Lua-script mods, sandboxed atomic extraction, import wired through FileHandler.
  • PR #95 — JavaBridge: import a Java Edition .jar, assess portability locally, decompile with CFR, and have a user-configured LLM generate a Bedrock .AntEgg mod (with consent gating + AI-port provenance). Rewrites, never runs, Java mods.

4. Cosmetics

  • PR #78 / #75 / #76 — in-game cape via a texture-override resource pack, real applied skin in the preview.
  • PR #81 — depth-layering fix (wings → cape → body → head accessories), ore-loader art fix.
  • PR #89 — Cosmetics status diagnostic (pure, unit-tested) + PNG skin import.

5. UI / UX

  • PR #78 — Mod Menu full-screen white-overlay fix.
  • PR #80 — splash & in-launcher motion overhaul (crystal-ore loader, staggered arrival, count-up stats).
  • PR #81 / #91 — Mod Menu focus-wash hardening.
  • PR #89 — 3D controller illustrations, nav-bar wordmark collision fix, ~30-font app-wide font picker (LauncherFonts), controller-connected toast, per-button CPS.
  • PR #92 — VIP Mod Menu (Screen B) opened by the in-game bind, with keyboard illustration.
  • PR #93 — Replay system (capture/review/export) shared by both Mod Menu screens.
  • PR #94 — PvP Suite V1.1: four overlay-only modules; Modules → General tab rename.

6. Combat / PvP modules

  • PR #91 — Hitboxes un-greyed, peer boxes + aim lines (protocol v5 yaw/pitch), chest-height target-box toggle, combo/item limitations documented.
  • PR #94 — Reach Indicator, Trajectory Prediction, Hit Prediction, Custom Kill Effects (all fail-closed, overlay-only).

7. Controller

  • PR #89 / #90 — 3D controller illustrations, CPS limiter, connection notification, remap layers, rumble strength, radial dead zone as default, illustration perf fix.

8. Performance / input hardening

  • PR #90 — Enter-in-chat crash fix (TextInputSanitizer), shader autofix, FPS optimizer (launcher-side only, honest scope).
  • PR #89 — CPS window fix, firework touch layer, "add server" fix.

9. Testing

  • 381 tests at V7 → 1,037 at PR #95 (0 failures, no mocks). Intermediate: 510 (PR #78), 597 (PR #83), 845 (PR #91), 901 (PR #93).

Part 2 — Best fonts

First, the honest constraint

GitHub sanitizes <style> blocks and inline style attributes in READMEs and release bodies, so you cannot reliably force a custom font on the text itself — it renders in the reader's system stack. Two practical consequences:

  1. For the description's live text: pick from system stacks (they render everywhere) — don't try to load a webfont.
  2. For fonts you actually control: use them in embedded banner/heading images (PNG/SVG), where any font renders exactly as designed.

So the list below is split accordingly, and I've starred the fonts your launcher already bundles (LauncherFonts), so release art and the app can share a face.

A. Live text — recommended system stacks

Role Stack Why
Body -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif GitHub's own default; maximum legibility on every OS
Headings same as body, font-weight: 600 Weight, not a new face, is what separates headings on GitHub
Code / commands ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace GitHub's code stack; aligns version strings and flags

B. Banner / heading-image fonts (ranked for a GitHub release description)

# Font * Type Best for Why it works
1 Inter * Sans Headings, body, UI mockups Neutral, superb at small sizes, huge weight range — the safest "modern tech" face
2 Montserrat * Sans Section headings, banners Geometric, confident; great for ALL-CAPS feature titles
3 Space Grotesk * Sans Wordmark, hero headings Slightly quirky, very "gaming-tech"; pairs with Inter body
4 Poppins * Sans Feature chips, badges Round geometric; friendly, reads well in pills
5 Manrope * Sans Sub-headings, stat labels Tight, modern, excellent numerals for "1,037 tests" callouts
6 Sora * Sans Headings, nav art Techy and crisp; strong at medium weights
7 Outfit * Sans Hero banner Clean variable geometric; great for large display text
8 Orbitron * Display Version tag / "V8" badge Sci-fi; use only for short accents, never body
9 Bebas Neue * Display Big ALL-CAPS section bars Condensed impact; ideal for "WHAT'S NEW" strips
10 Press Start 2P * Display Minecraft-flavoured accents Pixel font; perfect for a single playful badge, unreadable in bulk
11 JetBrains Mono * Mono Code blocks, version numbers, terminal shots Ligatures, clear 0/O and 1/l; ideal for ./gradlew commands
12 Fira Code * Mono Inline code art Same clarity, slightly softer than JetBrains
13 Merriweather * Serif Long-form release prose High readability in body text; good "changelog document" feel
14 Lora * Serif Quotes / callouts Warm, editorial contrast against sans headings
15 Playfair Display * Serif Hero heading (elegant mode) High-contrast display serif for a premium banner

* = bundled in this repo under app/src/main/res/font/ (29 faces total).

C. Pairings that look deliberate

  • Modern gaming (recommended for GlowberryClient): Space Grotesk (headings) + Inter (body) + JetBrains Mono (code).
  • Clean corporate: Montserrat (headings) + Open Sans (body) + Fira Code (code).
  • Premium/elegant: Playfair Display (hero) + Manrope (subheads) + JetBrains Mono (code).
  • Playful Minecraft accent: Bebas Neue or Press Start 2P for one badge only, with Inter for everything else.

D. Copy-paste stacks for embedded banners / external rendering

/* Headings */
font-family: "Space Grotesk", "Montserrat", -apple-system, "Segoe UI", sans-serif;

/* Body */
font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;

/* Code / versions */
font-family: "JetBrains Mono", ui-monospace, "SF Mono", Menlo, Consolas, monospace;

Biggest update so far....

Choose a tag to compare

@ChimeraAnt-DEV ChimeraAnt-DEV released this 27 Sep 13:29
74903c9

Summary

Implements the .AntEgg multi-language mod packaging format, adds a proximity voice chat module and an opt-in in-game resource-pack changer, and fixes the cosmetics/3D-preview/paper-cape defects plus the Mod Menu white-overlay bug.

Dependency: the preloader submodule pointer moves to preloader-android@antegg-mod-loader (commit 1ff3721). The submodule branch must be merged (or its commit made reachable) before this PR's pointer resolves.

Changes

.AntEgg mod packaging (core.antegg + preloader AntEggLoader)

  • ZIP container with a custom extension; egg.json manifest at the archive root (name, version, author, type, entry_point, optional dependencies, description).
  • Strict validation (Java AntEggManifest and C++ pl::runtime::AntEggManifest parse the same grammar): required fields, semantic version, type must agree with the entry-point extension, entry_point may not escape the package.
  • native: extracted .so's absolute path is handed to the preloader's existing native-mod injection entry point (ModManager.initializeLoadedMod). .AntEgg adds packaging/validation, not a second injection mechanism. The original spec calls this API "ApexAntLamina"; no class/symbol by that name exists in this tree — the pl preloader bridge is the API in question.
  • script: entry .lua runs on an embedded Lua VM (LuaJ, Lua 5.2) via AntEggScriptHost, which exposes a mod table (name, version, author, id, dir, sandbox, dependencies). Failures are returned, not thrown.
  • Sandboxed atomic extraction to getExternalFilesDir()/AntEggs/<mod-id>/ (internal fallback). Every ZIP entry is resolved and checked to stay inside the sandbox; the archive is staged in a temp sibling and moved into place only when complete, so a failed import leaves no partial mod.
  • Import wired through FileHandler; .antegg intent-filter path patterns/suffixes added; template + format docs at examples/antegg-template/.
  • Native uses zlib raw inflate (no new third-party ZIP dependency); JNI bound via AntEggBridge with Java_org_chimeramc_client_core_antegg_* symbols.

Proximity voice chat (core.voice + VoiceChatOverlay)

  • Peer link between Chimera users in the same world over LAN multicast UDP (VoiceTransport), raw 16 kHz mono PCM framing (VoiceProtocol), mixing (VoiceRegistry + VoiceChannel), device (VoiceAudioEngine).
  • Multi-channel support: a listener hears their own channel plus the open world channel in both directions, so switching to a private channel never cuts off someone standing next to you; two different private channels do not hear each other.
  • Mic capture with a runtime RECORD_AUDIO request; a denied permission still starts listen-only. ensureCapture/stopCapture handle a mic toggled on after a listen-only start.
  • Honest scope: distance/range needs a world position that lives in libminecraftpe.so (see the native-feed notes in AGENTS.md), so the module runs in channel mode — everyone on a reachable channel is audible. The overlay states this rather than pretending a range applies.

In-game pack changer (InGamePackChanger + PackChangerPanel)

  • Per-instance opt-in toggle in Instance Settings (GameVersion.inGamePackChangerEnabled, persisted in VersionProfileMetadata).
  • When enabled, the in-game Mod Menu's Packs section lists the instance's resource packs with a per-pack on/off toggle that rewrites minecraftpe/global_resource_packs.json, across every candidate game-data root.

Cosmetics / 3D preview / paper cape

  • Fixed the left arm and left leg base/overlay UVs (they pointed at neighbouring strips, so one side of the body sampled the wrong atlas region). Pinned by new SkinModelTest cases.
  • The built-in placeholder now paints from the same UV table the renderer samples, so it cannot drift from the model.
  • The cape texture now paints every face (back panel, front panel, side columns, edge rows) — previously the transparent strips showed as holes when the cape swung, reading as flapping paper.
  • The cape mesh is now depth-sorted per quad with two-sided shading; the old row-major paint order let a fold's far side paint over its near side.

Mod Menu white overlay

  • The full-screen translucent white wash was Android's default focus highlight: the overlay root is clickable, hence focusable, so a controller stick/d-pad input moved focus onto it and the framework painted the highlight. Fixed by making the root focusable="false" + defaultFocusHighlightEnabled="false" (XML and programmatically), while keeping children focusable for controller nav.

Testing

  • ./gradlew :app:assembleDebug — BUILD SUCCESSFUL.
  • ./gradlew :app:testDebugUnitTest — 510 tests, 0 failures, 0 errors.
  • Verified the three Java_org_chimeramc_client_core_antegg_AntEggBridge_* symbols are present in the packaged libpreloader.so inside the debug APK.
  • New tests: AntEggScriptLoadingTest, VoiceChannelTest, VoiceProtocolTest, VoiceModuleGroupingTest, InGamePackChangerTest, plus expanded SkinModelTest / CapeResourcePackBuilderTest.

Not done (deliberately, with reasons)

  • Hitboxes / Crystal Optimizer / Armor HUD live data. These need a native entity/camera feed. As documented at length in AGENTS.md (verified against the real libminecraftpe.so), game classes are stripped of exported symbols and the reachable RTTI vtables are pure-virtual interface bases, so there is no way to obtain Level*/ClientInstance* without per-build byte-pattern signatures. The modules keep their honest "awaiting game data" state rather than fabricating readings.
  • Lint: lintDebug already fails on ~355 pre-existing MissingTranslation errors unrelated to this change; not addressed here.

This change was created by Malice 🤔🤔

Bug fixes + 2 new mod menu modules

Choose a tag to compare

@ChimeraAnt-DEV ChimeraAnt-DEV released this 26 Sep 00:20
0ffd524

Switches the Installations tab to mcpe-planet.com, fixes three combat-module defects (settings not saving, and hit registration / aim settings adding input delay), and adds two new PvP modules: Hitboxes and Select Hit.

  1. Installations source → mcpe-planet.com

McpePlanetSource is added and registered first in SourceRegistry, so it becomes the active source out of the box. mcpedl.org is retained as an alternative — adding a mirror remains the documented two-step process (implement BedrockSource, add to all()), with no change to the UI, download client or import pipeline.

Verified against the live site rather than a hand-written fixture: 12 versions parsed (1.26.60.28/24, 26.51, 26.50) and the full POST download flow resolved end-to-end to a real wp-content/uploads/version/...apk.
2. Module settings not saving

Root cause: configNode() mapped every non-toggle config type to slider_int. Consequences:

The Crystal keybind rendered as a 0–100 slider and wrote a small integer over the stored key code.
The Aim Settings style radio lost its options entirely.

Fixed with schemaTypeFor(), which covers every ConfigType, plus InbuiltModuleProviderTypeTest pinning the mapping (including that a keybind must never collapse to a slider).

While there I found the _desc help strings and all the module scope notes had no consumer in code or layout — they were dead strings. They are now wired into the dialog, including an info node per combat module carrying its scope note. configDescriptionRes is an explicit switch rather than a name lookup, so a renamed key cannot silently bind to an unrelated string.
3. Hit registration / aim settings adding delay

A real bug, and the exact opposite of the module's stated purpose:

BURST_GAP_MS was 16L, just under one 60 Hz frame (16.7 ms). The smoothing filter therefore classified nearly every frame as a new gesture and reseeded constantly.
The reseed zeroed the filter, discarding (1 − smoothing) of each gesture's opening delta.

Both fixed in HitRegistrationMod and AimSettingsMod: window raised to 120 ms, and the filter is seeded with the frame instead of zero, so steady motion passes 1:1 and smoothing only damps frame-to-frame jitter. Tests updated to assert the first frame of a gesture is not attenuated and that 60 Hz frame pacing stays within one burst.
4. New: Hitboxes

Entity boxes plus an aim line. Players additionally get a red critical-hit line and a red best-combo box, both turning blue when aimed at.

HitboxProjector is pure (no Android/game types) and holds all the arithmetic: camera basis, box projection, crit band, combo box, and a crosshair slab test so the blue highlight cannot disagree with the geometry actually drawn. 18 tests.
The tests caught a real bug: Camera.forward() used the naive spherical form (sin yaw, …), which is counter-clockwise, while the documented Minecraft convention is clockwise from +Z. That would have mirrored every projected box horizontally once a real feed supplied yaw. Fixed, with new tests pinning the up vector too.
HitboxMod.EntitySource is the game-data seam. With no provider nothing is drawn — an invented box is worse than no box, because the player would aim at it.
The overlay is FLAG_NOT_TOUCHABLE and non-draggable, since boxes are world-positioned and the whole screen is the canvas.
  1. New: Select Hit

A small top-centre green/red pill (96×26 dp, deliberately clear of the crosshair and hotbar) showing when the next hit will land, with a combo count and a slim progress bar.

HitTimingSolver is pure; 13 tests. A click inside the window must not advance the combo or push the window out — counting a discarded click would make the indicator lie about both the streak and the next hit. A backwards clock is treated as a fresh engagement rather than producing a negative remaining time.
The window is clamped (50..2000 ms) and exposed as a slider, because the real cooldown varies by version.
Attack input is recorded from the paths that actually send an attack (mouse primary, and the controller mouse-button path in dispatchKeyEvent), before the preloader may consume the press — the player pressed attack either way, so the timing is the real input timing.

Honest limitations

Armor HUD still cannot display real durability, and Hitboxes cannot display real entity positions. I investigated rather than assuming: the preloader submodule exports only menu/HUD hooks, input handling and mod loading — there are no game-state entry points for entities, armor or position. Any values would have to be fabricated. Both DataSource/EntitySource are left as honest seams that render nothing (or a dimmed -), and the dialog now states this in-app rather than the feature appearing silently broken.

Fixing this needs new native hooks in the preloader submodule, which is a separate change.
Testing

381 unit tests, 0 failures, 0 errors (baseline on main: 322).
:app:compileDebugJavaWithJavac, :app:compileDebugKotlin and a full :app:assembleDebug all pass.
APK verified: lib/arm64-v8a/libgxcore.so present, and all six new classes present in the dex.
No mocks — every new test exercises real code paths.

Lint is unchanged: the project has no lint baseline and lintDebug already fails on ~355 pre-existing MissingTranslation errors, which is not a regression from this change.
Notes for reviewers

New modules are in ModIds.PVP_MODULES so they land in the PvP tab, and ModIds.requiresGameData() now marks three modules (armor, crystal, hitbox).
AGENTS.md updated with the new modules, the yaw convention, the config-description wiring, and the input-delay root cause.

BIG UPDATES

Choose a tag to compare

@ChimeraAnt-DEV ChimeraAnt-DEV released this 24 Sep 04:10
40cf12f

Changes since V6

Rebrand to Chimera Client (PR #66) — org.chimeramc.launcher → org.chimeramc.client across ~318 files, including namespace, applicationId and app name. The preloader submodule's JNI symbols were renamed to match. org.levimc.* classes and the prebuilt libgxcore.so/libinbuiltmods.so were left alone since they have no source and would UnsatisfiedLinkError. The org.chimeramc.xal.crypto pref key and games/org.chimeramc storage root were preserved so existing data isn't stranded.
Installations tab (PRs #61, #62) — new tab that lists Bedrock versions a mirror publishes and installs one as its own instance. Started on monster-mcpe.com (Cloudflare-gated, WebView required), then refactored to a pluggable BedrockSource/SourceRegistry abstraction defaulting to mcpedl.org (plain HTTP, no challenge — browser demoted to a 403 fallback). Failed installs keep the downloaded package for "Retry Import".
UI/branding overhaul (PR #63) — violet/magenta palette replacing the inherited green/cyan, shared card system (Widget.Chimera.Card* driven by dimens.xml), new splash and original ant-vector icon.
Navigation restored to top bar (PRs #64, #65) — the overhaul's vertical side rail could only fit ~2 of 6 tabs in landscape, so it was reverted and the original top bar brought back.
PvP Mod Menu tab (PR #67) — a PvP filter/section grouping Aim Settings, CPS Display and Snaplook, via ModIds.isPvpModule() + GROUP_PVP.
Combat modules (PR #68) — Armor HUD, Crystal Optimizer and Hit Registration, each built as decision logic behind an explicit game-data seam (no live game state is readable in this repo, so nothing fabricates a reading).
News push notification (PR #60) — FCM notification now uses a fixed "New Version Available" message instead of echoing the news item's own title/summary.

BIGGEST PVP/STABILITY/PREFORMANCE/FEATURE UPDATE !!!

Choose a tag to compare

@ChimeraAnt-DEV ChimeraAnt-DEV released this 22 Sep 01:38
d7e352e

BIGGEST UPDATE LOTS OF BUGS FIXES, FEATURES FOR CONTROLLER PLAYERS, BETTER UI CUSTOMIZATION, ANTI STICK DRIFT TOGGLE

More UI improvements, bug fixes, fps and overall launcher boost

Choose a tag to compare

@ChimeraAnt-DEV ChimeraAnt-DEV released this 19 Sep 17:54
433e7e6
V5

Merge pull request #55 from ChimeraAnt-DEV/feature/ui-glass-dynamic-c…

UI Improvements, illegal devamp

Choose a tag to compare

@ChimeraAnt-DEV ChimeraAnt-DEV released this 16 Sep 17:41
8fd9513

What this changes

Two things: fixing version imports for the bundles people actually have, and filling the two gaps in the top-level navigation.

Import fixes

  • .xapk/.apkm bundles now import. The extension gate only accepted .apk/.apks, so valid bundles for older Bedrock builds were refused before they were ever opened — even though the file picker advertises application/zip and the version-manager layout names .xapk. Bundle handling is now centralised in GameBundle, shared by the installer and the version-name lookup.
  • XAPK base-APK detection. XAPK bundles name their base APK after the package rather than base.apk, so the old check never found a base and the ABI gate then saw no native libraries and rejected the import.
  • Re-signed and older APKs are no longer rejected as "Not a Minecraft APK". When the package manifest cannot be read, Minecraft is now also identified by the presence of libminecraftpe.so, and the version name falls back to the file name.

Navigation

  • Mods is now a nav tab. It was previously reachable only from a home-screen card.
  • Controller bumper/D-pad tab switching (L1/R1, L2/R2, D-pad left/right, wrapping at both ends). LauncherTab is the single source of truth for tab order, activity mapping and key handling.
  • Two guards on that behaviour: ControllerActivity opts out via shouldHandleNavKeys() because it needs raw presses for button highlighting, and switching is suppressed during a game session.
  • Nav tabs gained press feedback via the existing DynamicAnim.applyPressScale, which respects the "show animations" setting and cancels cleanly when a tap becomes a scroll.
  • The nav bar itself already existed and is runtime-injected by BaseActivity; this extends it rather than adding a competing bar. A prototype focus_ring token was dropped, since no focus system consumed it.

Docs

  • AGENTS.md documents the nav architecture and its guards, and records that Java Edition is an unimplemented stub (see below), so these non-obvious constraints survive the next session.

Verification

  • ./gradlew :app:testDebugUnitTest :app:compileDebugKotlin :app:compileDebugJavaWithJavac — BUILD SUCCESSFUL, 100 tests, 0 failures (9 new LauncherTabTest, 5 new GameBundleTest).
  • ./gradlew :app:assembleDebug — full APK builds; libgxcore.so present in lib/arm64-v8a/.
  • There is no emulator or device in this environment, so on-device behaviour is unverified. GameBundleTest covers bundle detection against real archives.

Notes

  • The ABI/dual-ABI work is already in main (merged via #51), so it is not part of this PR. This branch was originally based on that work; the PR diff correctly shows only the changes above.
  • Java Edition is not implemented and is deliberately not added here. core/javaedition/JavaEditionModManager returns true from isJavaEditionSupported() unconditionally and points at /system/bin/java, which does not exist on Android; nothing consumes its launch config, and its strings are referenced by no layout or activity. It is documented as a stub so it is not mistaken for a working feature. Real support would require a bundled per-architecture JRE, a custom LWJGL, and a GL→GLES/Vulkan translation layer, and it conflicts with this project's Apache-2.0 license (PojavLauncher is GPL-3.0, Amethyst-Android is LGPL-3.0). Out of scope for this PR.

Major launcher Improvements

Choose a tag to compare

@ChimeraAnt-DEV ChimeraAnt-DEV released this 15 Sep 22:05
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.

UI layout revamp, improvements, and updates

Choose a tag to compare

@ChimeraAnt-DEV ChimeraAnt-DEV released this 15 Sep 15:51
70a3055

Upgrades the Chimera Launcher with four workstreams:

  1. Client-side hit registration (Bedrock)

    New inbuilt mod (ModIds.HIT_REGISTRATION) with configurable Aim Smoothing (0–95%), center crosshair overlay, and hit flash feedback.
    Exponential-moving-average look smoothing that only eases large swipes (keeps fine aim 1:1); nonzero delta passthrough untouched.
    Hooked into the real input pipeline: MinecraftActivity.pojavSendLookDelta (smoothing) and pojavSendMouseButton (flash). Overlay is a non-touchable window so no input is stolen.

  2. UI layout revamp + touch reactiveness

    Press-scale velocity-kicked springs + elevation + haptic feedback (UiTouchFeedback) on hero card, all quick-action cards, launch/version buttons, sign-in, mods/news/content view-all links., account avatars.

    Hero-card pulse + glow gated via isShowAnimations() / isEnableGlowEffects().

    Press feedback skips entirely when animations are disabled (reduced motion respect.

  3. Low Input Delay — stronger

    Replaced the idle 250 ms GPU redraw poll (4fps) with a near-free 500 ms menu-state flag check that only repaints on real pause-menu/HUD transitions in low-latency mode.

    Every touch (surface/button/joystick) now does an instant menu-state check that fires visibility refresh the moment the state flips (no stale overlay buttons after opening/closing the pause menu).

    PojavControls.setLowLatencyMode(...) now live-pokes the overlay on toggle so no path remains stalled..

  4. 64-bit + 32-bit instance support

    ABI badges (32-bit amber / 64-bit green) on the hero card, instance list, and version picker..
    Bitness-aware preflight (requireLauncherSupportsVersion / abiMismatchMessage) that surfaces a clear explanation before any loadLibrary instead of a mid-launch dlopen crash..
    64-bit-only prebuilts (gxcore, mtbinloader2, PlayFab/MSDK) are excluded/treated optional on 32-bit devices so a 32-bit launcher build no longer aborts..

    Note: Android locks each process to one bitness at install, so a 64-bit process cannot dlopen a 32-bit minecraftpe.so. The launcher handles this explicitly: detects, surfaces a clear error, and refuses to attempt an impossible load (rather than crashing) while running every 64-bit variant fully..

  5. Reduce Network Latency — stronger

    TCP_NODELAY + TCP Quick ACK + interactive buffer sizing (LowLatencyNetworkManager.configure(...)) now apply to every launcher OkHttp client: CurseForge, preloader signature rules, avatar fetches (Main/Base/Accounts/About), content downloads, GitHub release updater/news polls..
    DNS prefetch covers GitHub/CurseForge/Google + popular Bedrock multiplayer endpoints; background polls pause during active game sessions.

Validation

./gradlew :app:assembleDebug → BUILD SUCCESSFUL (includes CMake/native packaging; APK verified: lib/arm64-v8a/libgxcore.so, libinbuiltmods.so, libmtbinloader2.so)..

Testing notes

No Android emulator/KVM in dev — validated via full assemble + APK contents check.. On-device spots to check: hit-reg smoothing feel, crosshair/flash, low-latency overlay visibility after pause menu toggles, ABI badges/preflight for a imported 32-bit version, Wireshark/strace TCP_NODELAY on launcher sockets..

UI REVAMP + NEW PING STABLIZATION TOGGLE

Choose a tag to compare

@ChimeraAnt-DEV ChimeraAnt-DEV released this 12 Sep 23:05
30f5dfa
  1. UI revamp — visual richness and motion pass

    Richer accent palette: per-section gradient drawables for the hero card, launch, versions, mods, and content cards (card_*_gradient.xml), plus dark-theme variants in values-night/colors.xml, so screens feel visually distinct rather than re-skinned copies. Section headers gain a 3dp accent bar (section_accent_bar.xml).
    Micro-interactions: DynamicAnim.applyPressScale now adds spring elevation feedback on press alongside the existing scale, and instance cards already use it recursively. Card glow/elevation is applied via applyGlowEffects (hero card) and gated by the glow toggle.
    Live/animated elements: a subtly pulsing last-played hero card, a smooth ValueAnimator progress indicator for file imports (revealed on progress, hidden on completion/error), and animated stat counters (instances/mods pop-scale).
    Toggle compliance: all motion honors isShowAnimations() (pulse is stopped/started in onResume based on the flag); glow/elevation honors isEnableGlowEffects(). Dark/light theming respected throughout.

  2. Playtime tracking on the last-played instance card

    New PlaytimeManager persists per-instance accumulated playtime (SharedPreferences, 15s heartbeat, crash/interrupted-session cleanup in Application.init()).
    Wired into MinecraftActivity.kt session lifecycle (start from EXTRA_STORAGE_PROFILE_ID, heartbeat, stop in onDestroy).
    Displayed on the last-played hero card ("Xh Ym played") and per-instance in the instances list. Time accumulates across sessions and tracks real wall time (within one heartbeat interval).

  3. "Reduce Network Latency" toggle in Settings → Basic

    Labeled honestly — a launcher can't control server distance/ISP routing.
    LowLatencyNetworkManager:
    TCP_NODELAY socket factory for the launcher's own connections (News + GitHub release updater). Note: the socket factory deliberately delegates to SocketFactory.getDefault() — the inherited abstract SocketFactory.createSocket() is not callable directly.
    Background DNS prefetch of known endpoints (triggered when the toggle is enabled).
    A game-session quiet zone: non-essential news/update polling is paused while a session runs (NewsRepository.refreshIfStale, GithubReleaseUpdater, LauncherNewsMessagingService).