ScreenshotCompat

Cross-version seam for Screenshot#takeScreenshot and the main RenderTarget's accessor. Both are reflective, for different reasons — neither can be inlined later:

  • takeScreenshot: a compile-time break. Synchronous through 1.21.4, asynchronous from 1.21.5. One source tree is compiled against every node, so neither shape exists on all of them. 1.21.6's (RenderTarget, int, Consumer) overload is ignored on purpose: that downscale is GPU-side and absent from the older nodes, so scaling stays the caller's job.

  • The accessor: a runtime break. Minecraft#getMainRenderTarget compiles on every node, but at 26.2 it moved to GameRenderer — inside the 26.1.2 node's open-ended [26.1.2,) range.

Matched by SHAPE, never by name, as CommandsCompat: name strings aren't reobf'd, so "takeScreenshot" would stay mojmap and miss on Fabric intermediary / Forge SRG, while the Class references below are remapped by the build. That also means no Mappings dependency, so this works before the runtime name table loads — unlike ClientCommandCompat.

Each shape matches exactly one method: every grab overload takes a File or (26.2) a Minecraft first, and a no-arg method returning RenderTarget is unique on both owners in every version 1.18.2 .. 26.2.

Properties

Link copied to clipboard
private val accessor: (Minecraft) -> RenderTarget??
Link copied to clipboard
private val asyncTake: Method?

1.21.5 .. 26.2, unchanged the whole way.

Link copied to clipboard
private val syncTake: Method?

1.18.2 .. 1.21.4.

Functions

Link copied to clipboard
private fun call(m: Method, receiver: Any?, vararg args: Any?): Any?

receiver is null for the static takeScreenshot. Unwraps like CommandsCompat, so the game's own failure surfaces instead of the reflection wrapper.

Link copied to clipboard
private fun noArgRenderTarget(owner: Class<*>): Method?
Link copied to clipboard
fun request(mc: Minecraft, consumer: (NativeImage) -> Unit): Boolean

Take a screenshot of the main render target and hand the image to consumer. Render thread only.

Link copied to clipboard
private fun resolveAccessor(): (Minecraft) -> RenderTarget??

Order is load-bearing: through 26.1.2 both owners can answer and Minecraft's is the long-standing public one; on 26.2 it is gone and the lookup falls through to where the field now lives.