The bug

While taking a screenshot using the in-game F2 key, the game freezes for a second and does not take an accurate screenshot.

Code analysis

The reason why this is happening is because saving the screenshot is not done by a seperate thread. This means the lag time is determined by the writing speed of your harddrive.

Another reason which has probably a rather small impact is that in case frame buffering is enabled Minecraft iterates over all pixels in the screenshot and sets them in a BufferedImage . I do not see any advantage of this.

Here is a "fix" that solves this problem, however the ScreenshotSavingThread is only used as a local variable to demonstrate that it solves the problem. It should be rather in the class itself and also set the error message in case it fails:

saveScreenshot(File p_148259_0_, String p_148259_1_, int p_148259_2_, int p_148259_3_, Framebuffer p_148259_4_) method of the net.minecraft.util.ScreenShotHelper class (MCP 1.8 names)

saveScreenshot(File p_148259_0_, String p_148259_1_, int p_148259_2_, int p_148259_3_, Framebuffer p_148259_4_) if (OpenGlHelper.isFramebufferEnabled()) { var7 = new BufferedImage(p_148259_4_.framebufferWidth, p_148259_4_.framebufferHeight, 1); int var8 = p_148259_4_.framebufferTextureHeight - p_148259_4_.framebufferHeight; for ( int var9 = var8; var9 < p_148259_4_.framebufferTextureHeight; ++var9) { for ( int var10 = 0; var10 < p_148259_4_.framebufferWidth; ++var10) { var7.setRGB(var10, var9 - var8, pixelValues[var9 * p_148259_4_.framebufferTextureWidth + var10]); } } } else { var7 = new BufferedImage(p_148259_2_, p_148259_3_, 1); var7.setRGB(0, 0, p_148259_2_, p_148259_3_, pixelValues, 0, p_148259_2_); } File var12; if (p_148259_1_ == null ) { var12 = getTimestampedPNGFileForDirectory(var5); } else { var12 = new File(var5, p_148259_1_); } var12.createNewFile(); class ScreenshotSavingThread extends Thread { private final BufferedImage bufferedImage; private final File file; private ScreenshotSavingThread(BufferedImage bufferedImage, File file) { this .bufferedImage = bufferedImage; this .file = file; } @Override public void run() { try { ImageIO.write(bufferedImage, "png" , file); } catch (IOException e) { } } } new ScreenshotSavingThread(var7, var12).start();

Flaws with this design