Skip to content
Back to search

Zoomidy

by Unny984

Zoomify-style smooth zoom for Minecraft Bedrock Edition

  • 2 stars
  • Updated
client · 0.5.0

README0.5.0

Zoomidy

Smooth, animated zoom for Minecraft Bedrock Edition on Windows, in the spirit of Zoomify and MCBE-Win10-FOV-Changer.

Built as a client-side LeviLamina mod.

Features

Hold F to zoomOr switch to toggle. The key is rebindable to any keyboard key.
Animated transition0.2 s by default, with six easing curves to pick from.
Adjustable magnification4x by default; the scroll wheel changes it live while zoomed.
Hide the handThe first-person arm and held item disappear while zoomed.
Sensitivity scalingRelative (follows the zoom), fixed, or off.
Cinematic cameraOptional. The camera lags on the way in and coasts out after a flick.
In-game settings screen/zoomidy opens a real Minecraft form.

Requirements

  • Windows 10/11 x64
  • LeviLamina installed on the client, via LeviLauncher — either line below
  • The matching Minecraft Bedrock Edition client version
LeviLaminaMinecraft clientZoomidy variant
26.20.x1.26.20.4client (default)
26.10.x1.26.10.4client_26_10
26.51.x1.26.51.1client_26_51

The Store copy of Minecraft is usually newer than whatever LeviLamina supports, and the hooks here are resolved against the exact game binary. Use LeviLauncher to download and switch to the supported client version; it keeps it separate from your Store install. Each Zoomidy variant is built against, and only works with, the matching LeviLamina line — installing the wrong one will fail to load.

Install

Drop the built zoomidy folder into your client's mods/ directory, or install with lip. This installs the LeviLamina 26.20.x build:

lip install github.com/Unny984/Zoomidy

On LeviLamina 26.10.x, install the matching variant instead:

lip install github.com/Unny984/Zoomidy#client_26_10

On LeviLamina 26.51.x:

lip install github.com/Unny984/Zoomidy#client_26_51

Usage

Hold F. That is the whole thing.

Zoomidy watches the key rather than taking it over, so pick one Minecraft does not already use. If you bind it to a key that already does something, both will happen — but nothing gets locked away, and you can always rebind from the config file.

Settings screen

/zoomidy

The settings form only opens in a world this client is hosting — single-player, or a world you opened to LAN. Minecraft's form system belongs to the server half of the game, and there is no server half to talk to when you are a guest on somebody else's world. The sub-commands below work everywhere, and so does editing the config file.

Every change saves itself. There is no Apply button on either version — touch a control and it takes effect and is written to config.json straight away.

The 26.51 build uses the same screen as 26.20. The 26.10 build holds the same settings but shows them differently, because that version of LeviLamina predates the UI API the 26.20 screen is built on. The only screen it has that can report anything before it closes is a menu of buttons, so that is what it uses:

26.2026.10
LayoutOne page of controlsA menu, one screen per setting
NumbersSlidersA value with + / - buttons
ChoicesDropdownsA short list to pick from
Zoom keyType itPick from the usual candidates, or /zoomidy key for the rest

Sub-commands

These work in every world, including remote servers, because they never touch the form system.

/zoomidy status
/zoomidy reload
/zoomidy key <F|Z|SPACE|LSHIFT|F5|0x46|...>
/zoomidy activation <Hold|Toggle>
/zoomidy magnification <1.5-50>
/zoomidy transition <milliseconds> [curve]
/zoomidy hidehand <true|false>
/zoomidy sensitivity <Off|Relative|Fixed> [multiplier]
/zoomidy cinematic <true|false> [strength]

/zoomidy is registered on the client, so the command never reaches the server you are playing on and needs no permissions there.

Config file

mods/zoomidy/config/config.json. Edit it and run /zoomidy reload, or restart the game.

{
  "version": 1,
  "zoom": {
    "keyCode": 70,
    "activation": "Hold",
    "factor": 4.0,
    "minFactor": 1.5,
    "maxFactor": 50.0,
    "scrollToAdjust": true,
    "scrollStep": 1.2,
    "rememberScrolledFactor": false
  },
  "animation": { "durationSeconds": 0.2, "curve": "EaseOutQuad" },
  "view": { "hideHand": true },
  "sensitivity": { "mode": "Relative", "multiplier": 1.0 },
  "cinematic": { "enabled": false, "strength": 0.6 }
}

keyCode is a Windows virtual-key code; 70 (0x46) is F.

How it works

PieceMechanism
The zoomHooks LevelRendererPlayer::getFov and divides the answer.
Hiding the handSkips ItemInHandRenderer::renderFirstPerson for the frame.
The keyListens to ll::event::KeyInputEvent, gated on the pointer being locked, so it does not fire while you are typing in chat.
SensitivityRewrites dx/dy on ll::event::MouseInputEvent, carrying the sub-count remainder forward so slow aiming survives a 0.25x scale.
Cinematic cameraBanks the movement, then drains it a frame at a time from a MouseMapper::tick hook and feeds it back through Mouse::feed.
Scroll to adjustCancels the wheel event while zoomed, so the hotbar does not move with it.
Settings screenll::ui::CustomForm on 26.20, a menu of ll::form::SimpleForms on 26.10. Built on the server thread either way.

Why the camera coast needs its own hook

A camera that keeps turning after the mouse stops cannot be driven by mouse events, because during a coast there are none. Filtering the events in place can only ever slow the camera down. So the movement is banked instead and paid out from MouseMapper::tick, which runs once per frame on the same thread the real events arrive on, immediately before the queue it is handed gets drained.

Guards, since this synthesises input rather than only filtering it: the banked motion is capped, the per-frame step is capped so a hitch cannot release it all at once, a re-entrancy flag keeps the synthetic events out of the filter that produced them, and the drain stops entirely once the pointer is released so it can never push movement into an open menu.

A note on the zoom curve

The magnification is interpolated geometrically (factor ^ eased) rather than linearly. Perceived zoom is logarithmic — 1x → 2x feels like the same amount of movement as 2x → 4x — so a linear ramp crawls through the barely-zoomed range and then lurches at the end. The endpoints are still exactly 1x and the configured magnification.

Building

Needs xmake, plus both Windows toolchains — clang-cl for the 26.20 and 26.51 builds and MSVC for the 26.10 one. For clang-cl, install LLVM or add C++ Clang Compiler for Windows in the Visual Studio Installer. The 26.51 build needs LLVM 22 or newer; the clang that ships with Visual Studio is too old for its headers.

xmake f -p windows -a x64 -m release -y
xmake

This builds against LeviLamina 26.20.x by default. For the 26.10.x or 26.51.x line, pass the version explicitly:

xmake f -p windows -a x64 -m release --levilamina_version=26.10 -y
xmake
xmake f -p windows -a x64 -m release --levilamina_version=26.51 -y
xmake

The packed mod ends up in bin/.

The compiler is not a free choice. xmake.lua picks it from the target version, and it has to: LeviLamina's event ids are a hash of a type name the compiler produces, and the event classes live in an inline namespace that MSVC and clang spell differently. 26.20 and 26.51 are built with clang and 26.10 with MSVC, so a mod compiled with the other one registers its listeners under ids that nothing ever emits — it loads, reports no error, and then quietly does nothing.

License

See LICENSE.

Install Zoomidy

Run this in your server or client folder with lip:

lip install github.com/Unny984/Zoomidy#client@0.5.0
Download from GitHub