SimpleRecorder
A Minecraft client-side mod: press F8 to start or stop recording. By default it exports animated AVIF, with GIF as a compatibility fallback. Defaults are 30 FPS with width and height each scaled to 50%.
- Environment: Client only — no server installation required
- MODID:
simplerecorder(Forge modIds must be lowercase; the display name isSimpleRecorder)
Features
- F8 to start / stop with one key; rebindable in Options → Controls → Key Binds.
- F9 opens in-game settings; also accessible via Mods → SimpleRecorder → Config.
- Defaults to AVIF animation, 30 FPS, 50% width × 50% height, infinite loop.
- Automatically falls back to GIF when AVIF is unavailable, with the reason shown in chat.
- Config supports hot reload: edit the TOML file and the next recording uses the new values — no restart needed.
- A red dot +
REC mm:ssindicator appears in the top-right while recording; this indicator is not included in the output file. - Jade/WTHIT and other HUD info: frames are captured at
RenderGuiEvent.PostwithLOWESTpriority and flushed beforehand, so NORMAL-priority overlays such as Jade have already drawn; screenshots/recordings include block/entity info. - High-load settings warning: warns in chat when estimated pixel throughput is high enough to risk frame drops.
- Asynchronous PBO capture: 3 rotating PBOs + fences; the render thread never does synchronous readback and never creates
NativeImage; scaling and encoding happen on background threads. - RGB→YUV via OpenGL shader by default; falls back to multi-threaded CPU conversion (4 threads by default, capped at logical CPU count).
- On first launch, automatically downloads the official
avifenc(up to 1 minute), then caches it for reuse; no third-party binaries are bundled in the jar. - Drops new frames when the encode queue is full, so the game never stalls.
- AVIF uses the configured frame rate as its time base; dropped frames are duplicated to preserve real duration.
- Automatically stops and exports on window resize or when leaving the world.
- Shows a clickable file path in chat when export completes.
This is a pure client-side mod. It adds no blocks, items, or network packets, and does not affect server registries.
AVIF Encoder & Architecture
The mod no longer bundles avifenc in the jar. Instead, it checks for an available encoder on the client at startup; if none is found, it asynchronously downloads the official libavif release, waiting up to 1 minute. Successful downloads are cached at:
config/simplerecorder/avif/<platform>/avifenc[.exe]
Subsequent launches reuse the cache without going online.
| Platform | Official build | Handling |
|---|---|---|
| Windows x64 | Yes | Auto-download at startup |
| Linux x64 | Yes | Auto-download at startup |
| macOS arm64 | Yes | Auto-download at startup |
| Linux arm64 / Android | No | No default community build; set avif.encoderPath or avif.downloadUrl, or provide your own |
| macOS x64 | No | Same as above |
- Downloads prefer the official
github.comrelease and fall back to thegh-proxy.commirror; total timeout is 1 minute. - No re-download when a local cache exists,
avifencis on PATH, orencoderPathis configured. - On download failure, missing official build for the platform, or a non-executable file, recording automatically falls back to GIF and the reason is shown in chat.
- On Android,
os.nameis usuallyLinuxand the architecture isaarch64; provide an Android-executableavifencpath or a custom zip download URL.
Downloaded binaries come from the official libavif release. See THIRD_PARTY_NOTICES.md for license and copyright info.
Usage
- Enter a world.
- Press F8 to start recording;
● REC 00:00appears in the top-right. - Press F8 again to stop. Chat reports that export is in progress, then shows the path when done.
- Files are saved in the game directory under
screenshots/:simplerecorder-2026-11-01_00-00-00.avif- Fallback:
simplerecorder-2026-11-01_00-00-00.gif
F8 works in-world and with inventory/pause menus open; it does not trigger inside the Controls → Key Binds screen.
Settings
In-Game
Press F9 to open the settings screen. Adjustable options:
- Output format: AVIF / GIF
- Frame rate: 5–60
- Scale: 10%–100%
- AVIF quality: 20–100
- AVIF speed: 5–10 (higher = faster, larger files)
- YUV conversion: OPENGL (default) / MULTITHREAD
- CPU threads: 1–logical CPU count (MULTITHREAD only)
- Loop: on / off
Click "Done" to write the config file and close.
Config File
config/simplerecorder-client.toml is generated on first launch:
[output]
format = "AVIF" # AVIF / GIF
fps = 30
scale = 0.5 # 0.5 = 50% of width and height
loop = true
warnHighSettings = true
[avif]
quality = 60 # 20-100
speed = 8 # 5-10
conversion = "OPENGL" # OPENGL (default) or MULTITHREAD
cpuThreads = 4 # 1-logical CPU count
encoderPath = "" # custom avifenc executable path
downloadUrl = "" # optional: zip URL containing avifenc
Hot reload: Forge watches this file; the mod also checks file mtime/size once per second as a fallback. Saved values take effect on the next recording. If the in-game settings screen is open, external edits refresh the UI too.
cpuThreads defaults to 4 and is capped at the logical CPU count; single-core machines are limited to 1. GPU conversion always uses YUV444; the CPU fallback uses 4:2:0 for even dimensions and 4:4:4 for odd dimensions.
Changes only affect the next recording; an in-progress recording is never switched mid-way.
Capture Scope & Technical Notes
- Normally captures the main render target after HUD rendering, so crosshair, hotbar, health, and other HUD elements are included.
- When inventory, pause menu, chat, or other screens are open, capture happens after Screen rendering.
- The recording indicator is drawn after capture, so it never appears in the output.
- HUD overlays such as toasts and Jade tips are included as long as they draw at NORMAL priority; the recording indicator is drawn after capture and remains excluded.
- By default, 1920×1080 is captured as 960×540; scaling uses 2×2 box averaging.
- Asynchronous PBO capture: the render thread only does
glReadPixelsfrom the framebuffer into 3 rotating PBOs and inserts fences; after fence completion, it maps the PBO in the current GL context and hands the mapped memory to a background scaling thread. The background thread flips and scales, then the render thread unmaps and hands aScaledFrameto the encoder. - No more
NativeImagecreation, no per-frame 8 MB pixel array allocation, and no synchronousgetPixelsRGBAreadback. Scaling output reuses buffers viaFramePool. - OpenGL YUV: a fullscreen-triangle shader samples the main framebuffer with 2×2 box filtering, performs BT.601 limited-range RGB→YUV, and packs YUV444 into an RGBA8 target; the PBO reads YUV directly, so the CPU does no per-pixel conversion.
- CPU fallback:
MULTITHREADmode splits rows into bands and converts in parallel with a daemon thread pool; defaults to 4 threads, adjustable from 1 to logical CPU count, automatically limited to 1 on single-core. - AVIF: each frame is converted to Y4M (4:4:4 on GPU; 4:2:0 for even and 4:4:4 for odd dimensions on CPU) and streamed into
avifenc --stdin; no intermediate frames touch disk. - GIF: each frame builds a 5-bit RGB histogram + weighted median-cut adaptive palette of up to 256 colors, then LZW via ImageIO.
- Each frame carries a capture timestamp. GIF delays are written on an accumulated 1/100-second grid; AVIF uses the configured frame rate as its time base and duplicates frames on drops, so output duration matches real time without "fast-forwarding."
- With F1 hiding the HUD and no screen open, capture happens after world rendering, so only the world is captured (no HUD, no top-right indicator).
File Size
- AVIF is typically an order of magnitude smaller than GIF; a 1280×747, 30 FPS game capture commonly stays within a few hundred KB per second, depending on quality and scene complexity.
- GIF lacks modern inter-frame compression; 1280×747 / 30 FPS is roughly 6–7 MB/s, so one minute can reach 400 MB. Prefer AVIF for long recordings.
Tests cover GIF frame delay/loop/duplicate-frame merging/palette/end-to-end color, PBO bottom-row flip, 50% scaling, CPU YUV banded conversion, and actual animated AVIF encoding when a local avifenc is available. CI without an encoder skips the AVIF cases.

