diff --git a/game/client/.gitignore b/game/client/.gitignore
index c5dcc39b7..40e8b0596 100644
--- a/game/client/.gitignore
+++ b/game/client/.gitignore
@@ -1,3 +1,4 @@
 build
 logs
-dumpTextures
\ No newline at end of file
+dumpTextures
+out
\ No newline at end of file
diff --git a/game/client/src/main/java/net/minecraft/client/Minecraft.java b/game/client/src/main/java/net/minecraft/client/Minecraft.java
index f5ac77198..bbe419bee 100644
--- a/game/client/src/main/java/net/minecraft/client/Minecraft.java
+++ b/game/client/src/main/java/net/minecraft/client/Minecraft.java
@@ -2399,7 +2399,7 @@ public class Minecraft
         }
     }
 
-    public PacketHandlerClient getSendQueue() {
+    public @Nullable PacketHandlerClient getSendQueue() {
         if (this.thePlayer instanceof PlayerLocalMultiplayer) {
             return ((PlayerLocalMultiplayer) this.thePlayer).sendQueue;
         } else {
diff --git a/game/client/src/main/java/net/minecraft/client/gui/ButtonElement.java b/game/client/src/main/java/net/minecraft/client/gui/ButtonElement.java
index a5a4beb6e..520786c8e 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/ButtonElement.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/ButtonElement.java
@@ -128,17 +128,17 @@ public class ButtonElement extends Gui implements GuiElement
         return this.enabled && mouseX >= this.xPosition && mouseY >= this.yPosition && mouseX < this.xPosition + this.width && mouseY < this.yPosition + this.height;
     }
     
-    public ButtonElement setListener(Listener<ButtonElement> listener) {
+    public @NotNull ButtonElement setListener(@Nullable Listener<ButtonElement> listener) {
     	this.listener = listener;
     	return this;
     }
 
-    public ButtonElement mute() {
+    public @NotNull ButtonElement mute() {
         this.playSound = false;
         return this;
     }
 
-    public ButtonElement hide() {
+    public @NotNull ButtonElement hide() {
         this.visible = false;
         return this;
     }
diff --git a/game/client/src/main/java/net/minecraft/client/gui/Gui.java b/game/client/src/main/java/net/minecraft/client/gui/Gui.java
index 8d99fbaa7..a5630757e 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/Gui.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/Gui.java
@@ -210,8 +210,8 @@ public class Gui {
     }
 
     public void addTexturedModalRect(@NotNull TessellatorGeneral tessellator, final int x, final int y, final int u, final int v, final int width, final int height) {
-        final float uScale = 0.00390625F;
-        final float vScale = 0.00390625F;
+        final float uScale = 1.0f / 256.0f;
+        final float vScale = 1.0f / 256.0f;
         tessellator.addVertexWithUV(x, y + height, this.zLevel, (u) * uScale, (v + height) * vScale);
         tessellator.addVertexWithUV(x + width, y + height, this.zLevel, (u + width) * uScale, (v + height) * vScale);
         tessellator.addVertexWithUV(x + width, y, this.zLevel, (u + width) * uScale, (v) * vScale);
diff --git a/game/client/src/main/java/net/minecraft/client/gui/ScreenSignEditor.java b/game/client/src/main/java/net/minecraft/client/gui/ScreenSignEditor.java
index ace3a5240..c484ff194 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/ScreenSignEditor.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/ScreenSignEditor.java
@@ -6,24 +6,45 @@ import net.minecraft.client.input.InputType;
 import net.minecraft.client.input.controller.ControllerInput;
 import net.minecraft.client.option.GameSettings;
 import net.minecraft.client.render.TileEntityRenderDispatcher;
+import net.minecraft.client.render.renderer.BlendFactor;
 import net.minecraft.client.render.renderer.GLRenderer;
 import net.minecraft.client.render.renderer.State;
-import net.minecraft.core.block.Block;
-import net.minecraft.core.block.BlockLogicSign;
-import net.minecraft.core.block.Blocks;
+import net.minecraft.client.render.tessellator.TessellatorGeneral;
+import net.minecraft.client.render.texture.stitcher.IconCoordinate;
+import net.minecraft.client.render.texture.stitcher.TextureRegistry;
+import net.minecraft.core.block.*;
 import net.minecraft.core.block.entity.TileEntitySign;
 import net.minecraft.core.enums.EnumSignPicture;
 import net.minecraft.core.lang.I18n;
 import net.minecraft.core.net.packet.PacketSignUpdate;
+import net.minecraft.core.sound.SoundCategory;
+import net.minecraft.core.util.Nullability;
 import net.minecraft.core.util.helper.ChatAllowedCharacters;
+import net.minecraft.core.util.helper.DyeColor;
 import org.jetbrains.annotations.NotNull;
 import org.joml.Math;
 import org.lwjgl.input.Keyboard;
 
+import java.util.Objects;
+
 public class ScreenSignEditor extends Screen {
+    private static final @NotNull String ALLOWED_CHARACTERS;
+    static {
+        ALLOWED_CHARACTERS = ChatAllowedCharacters.ALLOWED_CHARACTERS;
+    }
+
+    protected @NotNull String screenTitle;
+
+    private final @NotNull TileEntitySign entitySign;
+    private int updateCounter;
+    private int editLine;
+    private int yOffset = 0;
+
+    private static final float SMALL_SIGN_SIZE = 3f;
+
     private boolean inKeyboard = false;
 
-    public ScreenSignEditor(@NotNull TileEntitySign sign) {
+    public ScreenSignEditor(final @NotNull TileEntitySign sign) {
         this.screenTitle = I18n.getInstance().translateKey("gui.edit_sign.label.title");
         this.editLine = 0;
         this.entitySign = sign;
@@ -34,37 +55,34 @@ public class ScreenSignEditor extends Screen {
         this.buttons.clear();
         Keyboard.enableRepeatEvents(true);
 
-        Block<?> block = this.entitySign.getBlock();
+        final @NotNull Block<?> block = this.entitySign.getBlock();
         if (block == Blocks.SIGN_POST_PLANKS_OAK) {
             this.yOffset = 36;
         }
 
         this.buttons.add(new ButtonElement(0, this.width / 2 - 100, 150 + 50 + this.yOffset, I18n.getInstance().translateKey("gui.edit_sign.button.done")));
 
-        this.buttons.add(new ButtonElement(1, this.width / 2 - 20, 120 + 50 + this.yOffset, 20, 20, "<"));
-        this.buttons.add(new ButtonElement(2, this.width / 2, 120 + 50 + this.yOffset, 20, 20, ">"));
-
         boolean wallSign = false;
         if (Block.hasLogicClass(block, BlockLogicSign.class)) {
             wallSign = !((BlockLogicSign) block.getLogic()).isFreeStanding;
         }
 
-        add(new ListenerButtonElement(30, this.width / 2 - 50, 67 + (wallSign ? 31 : 0), 100, 12, "")
+        this.add(new ListenerButtonElement(30, this.width / 2 - 50, 67 + (wallSign ? 31 : 0), 100, 12, "")
             .setActionListener(() -> {
                 this.editLine = 0;
                 this.inKeyboard = true;
             })).mute().hide();
-        add(new ListenerButtonElement(30, this.width / 2 - 50, 12 + 67 + (wallSign ? 31 : 0), 100, 12, "")
+        this.add(new ListenerButtonElement(30, this.width / 2 - 50, 12 + 67 + (wallSign ? 31 : 0), 100, 12, "")
             .setActionListener(() -> {
                 this.editLine = 1;
                 this.inKeyboard = true;
             })).mute().hide();
-        add(new ListenerButtonElement(30, this.width / 2 - 50, 12 * 2 + 67 + (wallSign ? 31 : 0), 100, 12, "")
+        this.add(new ListenerButtonElement(30, this.width / 2 - 50, 12 * 2 + 67 + (wallSign ? 31 : 0), 100, 12, "")
             .setActionListener(() -> {
                 this.editLine = 2;
                 this.inKeyboard = true;
             })).mute().hide();
-        add(new ListenerButtonElement(30, this.width / 2 - 50, 12 * 3 + 67 + (wallSign ? 31 : 0), 100, 12, "")
+        this.add(new ListenerButtonElement(30, this.width / 2 - 50, 12 * 3 + 67 + (wallSign ? 31 : 0), 100, 12, "")
             .setActionListener(() -> {
                 this.editLine = 3;
                 this.inKeyboard = true;
@@ -79,7 +97,15 @@ public class ScreenSignEditor extends Screen {
         // I have no idea how the hell the world is null sometimes
         // but thaboard was getting a crash from the world being null
         if (this.mc.currentWorld != null && this.mc.currentWorld.isClientSide) {
-            this.mc.getSendQueue().addToSendQueue(new PacketSignUpdate(this.entitySign.x, this.entitySign.y, this.entitySign.z, this.entitySign.signText, this.entitySign.getPicture().getId(), this.entitySign.getColor().id));
+            Objects.requireNonNull(this.mc.getSendQueue())
+                .addToSendQueue(
+                    new PacketSignUpdate(
+                        this.entitySign.x, this.entitySign.y, this.entitySign.z,
+                        this.entitySign.signText,
+                        this.entitySign.getPicture().getId(),
+                        this.entitySign.getColor().id
+                    )
+                );
         }
     }
 
@@ -89,7 +115,7 @@ public class ScreenSignEditor extends Screen {
     }
 
     @Override
-    protected void buttonClicked(@NotNull ButtonElement button) {
+    protected void buttonClicked(@NotNull final ButtonElement button) {
         if (!button.enabled) {
             return;
         }
@@ -97,24 +123,10 @@ public class ScreenSignEditor extends Screen {
             this.entitySign.setChanged();
             this.mc.displayScreen(null);
         }
-        if (button.id == 1) {
-            int id = this.entitySign.getPicture().getId();
-            int lastId = id - 1;
-            if (lastId < 0) lastId = EnumSignPicture.values().length - 1;
-            this.entitySign.setPicture(EnumSignPicture.values()[lastId]);
-            this.entitySign.setChanged();
-        }
-        if (button.id == 2) {
-            int id = this.entitySign.getPicture().getId();
-            int nextId = id + 1;
-            if (nextId >= EnumSignPicture.values().length) nextId = 0;
-            this.entitySign.setPicture(EnumSignPicture.values()[nextId]);
-            this.entitySign.setChanged();
-        }
     }
 
     @Override
-    public void keyPressed(char eventCharacter, int eventKey, int mx, int my) {
+    public void keyPressed(final char eventCharacter, final int eventKey, final int mx, final int my) {
         if (eventKey == Keyboard.KEY_ESCAPE) {
             this.entitySign.setChanged();
             this.mc.displayScreen(null);
@@ -128,17 +140,90 @@ public class ScreenSignEditor extends Screen {
         if (eventKey == Keyboard.KEY_BACK && !this.entitySign.signText[this.editLine].isEmpty()) {
             this.entitySign.signText[this.editLine] = this.entitySign.signText[this.editLine].substring(0, this.entitySign.signText[this.editLine].length() - 1);
         }
-        if ((allowedCharacters.indexOf(eventCharacter) >= 0 || Character.isLetterOrDigit(eventCharacter)) && this.entitySign.signText[this.editLine].length() < TileEntitySign.MAX_LINE_SIZE) {
+        if ((ALLOWED_CHARACTERS.indexOf(eventCharacter) >= 0 || Character.isLetterOrDigit(eventCharacter)) && this.entitySign.signText[this.editLine].length() < TileEntitySign.MAX_LINE_SIZE) {
             this.entitySign.signText[this.editLine] += eventCharacter;
         }
     }
 
     @Override
-    public void render(int mx, int my, float partialTick) {
+    public void mouseClicked(final int mx, final int my, final int buttonNum) {
+        super.mouseClicked(mx, my, buttonNum);
+
+        final @NotNull EnumSignPicture lastPicture;
+        final @NotNull EnumSignPicture nextPicture;
+        {
+            final int currentPictureIndex = Nullability.mapOr(this.entitySign.getPicture(), 0, EnumSignPicture::getId);
+
+            final int lastPictureIndex;
+            if (currentPictureIndex <= 0) {
+                lastPictureIndex = EnumSignPicture.values().length - 1;
+            } else {
+                lastPictureIndex = currentPictureIndex - 1;
+            }
+            lastPicture = Objects.requireNonNull(EnumSignPicture.fromId(lastPictureIndex));
+
+            final int nextPictureIndex;
+            if (currentPictureIndex >= EnumSignPicture.values().length - 1) {
+                nextPictureIndex = 0;
+            } else {
+                nextPictureIndex = currentPictureIndex + 1;
+            }
+            nextPicture = Objects.requireNonNull(EnumSignPicture.fromId(nextPictureIndex));
+        }
+
+        final Block<?> block = this.entitySign.getBlock();
+
+        final boolean isFreeStanding;
+        if (Block.hasLogicClass(block, BlockLogicSign.class)) {
+            final BlockLogicSign sign = (BlockLogicSign) block.getLogic();
+            isFreeStanding = sign.isFreeStanding;
+        } else {
+            isFreeStanding = false;
+        }
+
+        final int yOffset;
+        if (isFreeStanding) {
+            yOffset = -29;
+        } else {
+            yOffset = -2;
+        }
+
+        final double width = 24 * SMALL_SIGN_SIZE;
+        final double height = 24 * SMALL_SIGN_SIZE;
+
+        // Left sign
+        {
+            final int x = (this.width / 2) - (int) (24 * SMALL_SIGN_SIZE * 0.5) - (int) (24 * SMALL_SIGN_SIZE * 1.5);
+            final int y = (int) (1.0625f * 93.75f) + yOffset + 5;
+
+            if (mx >= x && mx <= x + width && my >= y && my <= y + height) {
+                this.entitySign.setPicture(lastPicture);
+                this.entitySign.setChanged();
+
+                this.mc.sndManager.playSound("random.click", SoundCategory.GUI_SOUNDS, 1.0F, 1.0F);
+            }
+        }
+
+        // Right sign
+        {
+            final int x = (this.width / 2) - (int) (24 * SMALL_SIGN_SIZE * 0.5) + (int) (24 * SMALL_SIGN_SIZE * 1.5);
+            final int y = (int) (1.0625f * 93.75f) + yOffset + 5;
+
+            if (mx >= x && mx <= x + width && my >= y && my <= y + height) {
+                this.entitySign.setPicture(nextPicture);
+                this.entitySign.setChanged();
+
+                this.mc.sndManager.playSound("random.click", SoundCategory.GUI_SOUNDS, 1.0F, 1.0F);
+            }
+        }
+    }
+
+    @Override
+    public void render(final int mx, final int my, final float partialTick) {
         GLRenderer.setColor4f(1f, 1f, 1f, 1f);
         if (this.inKeyboard && (GameSettings.FORCE_ONSCREEN_KEYBOARD.value || this.mc.inputType == InputType.CONTROLLER) && !(this.mc.currentScreen instanceof ScreenKeyboard)) {
             if (this.editLine < this.entitySign.signText.length) {
-                ScreenKeyboard keyboard = new ScreenKeyboard(this, null,
+                final ScreenKeyboard keyboard = new ScreenKeyboard(this, null,
                     (s) -> {
                         this.entitySign.signText[this.editLine] = s;
                         if (this.editLine < this.entitySign.signText.length - 1) {
@@ -154,22 +239,26 @@ public class ScreenSignEditor extends Screen {
                 this.mc.displayScreen(keyboard);
             }
         }
-        renderBackground();
-        drawStringCenteredShadow(this.fontRenderer, this.screenTitle, this.width / 2, 40, 0xffffff);
+        this.renderBackground();
+        this.drawStringCenteredShadow(this.fontRenderer, this.screenTitle, this.width / 2, 40, 0xffffff);
         GLRenderer.pushFrame();
         GLRenderer.modelM4f().translate((float) this.width / 2, 0.0F, 50F);
-        float scale = 93.75F;
+        final float scale = 93.75F;
         GLRenderer.modelM4f().scale(-scale, -scale, -scale);
         GLRenderer.modelM4f().rotateY(Math.PI_f);
-        Block<?> block = this.entitySign.getBlock();
+        final Block<?> block = this.entitySign.getBlock();
+
+        final boolean isFreeStanding;
         if (Block.hasLogicClass(block, BlockLogicSign.class)) {
-            BlockLogicSign sign = (BlockLogicSign) block.getLogic();
+            final BlockLogicSign sign = (BlockLogicSign) block.getLogic();
             if (sign.isFreeStanding) {
-                float signAngle = (float) ((this.entitySign.getBlockMeta() & BlockLogicSign.MASK_SIDE) * 360) / 16F;
+                isFreeStanding = true;
+                final float signAngle = (float) ((this.entitySign.getBlockMeta() & BlockLogicSign.MASK_SIDE) * 360) / 16F;
                 GLRenderer.modelM4f().rotateY(Math.toRadians(signAngle));
                 GLRenderer.modelM4f().translate(0.0F, -1.0625F, 0.0F);
             } else {
-                int meta = this.entitySign.getBlockMeta() & BlockLogicSign.MASK_SIDE;
+                isFreeStanding = false;
+                final int meta = this.entitySign.getBlockMeta() & BlockLogicSign.MASK_SIDE;
                 float signAngle = 0.0F;
                 if (meta == 2) {
                     signAngle = 180F;
@@ -183,6 +272,8 @@ public class ScreenSignEditor extends Screen {
                 GLRenderer.modelM4f().rotateY(Math.toRadians(signAngle));
                 GLRenderer.modelM4f().translate(0.0F, -1.0625F, 0.0F);
             }
+        } else {
+            isFreeStanding = false;
         }
 
         if ((this.updateCounter / 6) % 2 == 0) {
@@ -194,13 +285,109 @@ public class ScreenSignEditor extends Screen {
         GLRenderer.disableState(State.BLEND);
         GLRenderer.popFrame();
 
-        drawStringCenteredShadow(this.fontRenderer, I18n.getInstance().translateKey(this.entitySign.getPicture().getLanguageKey()), this.width / 2, 100 + 50 + this.yOffset, 0xFFFFFF);
+        this.zLevel = 100.0f;
+        this.drawStringCenteredShadow(this.fontRenderer, I18n.getInstance().translateKey(this.entitySign.getPicture().getLanguageKey()), this.width / 2, 100 + 50 + this.yOffset, 0xFFFFFF);
+        this.zLevel = 0.0f;
+
+        final int yOffset;
+        if (isFreeStanding) {
+            yOffset = -29;
+        } else {
+            yOffset = -2;
+        }
+
+        final @NotNull EnumSignPicture lastPicture;
+        final @NotNull EnumSignPicture nextPicture;
+        {
+            final int currentPictureIndex = Nullability.mapOr(this.entitySign.getPicture(), 0, EnumSignPicture::getId);
+
+            final int lastPictureIndex;
+            if (currentPictureIndex <= 0) {
+                lastPictureIndex = EnumSignPicture.values().length - 1;
+            } else {
+                lastPictureIndex = currentPictureIndex - 1;
+            }
+            lastPicture = Objects.requireNonNull(EnumSignPicture.fromId(lastPictureIndex));
+
+            final int nextPictureIndex;
+            if (currentPictureIndex >= EnumSignPicture.values().length - 1) {
+                nextPictureIndex = 0;
+            } else {
+                nextPictureIndex = currentPictureIndex + 1;
+            }
+            nextPicture = Objects.requireNonNull(EnumSignPicture.fromId(nextPictureIndex));
+        }
+
+        this.drawFakeSign(
+            (this.width / 2) - (int) (24 * SMALL_SIGN_SIZE * 0.5) - (int) (24 * SMALL_SIGN_SIZE * 1.5),
+            (int) (1.0625f * 93.75f) + yOffset + 5,
+            mx, my,
+            block, this.entitySign.getBlockMeta(),
+            lastPicture
+        );
+
+        this.drawFakeSign(
+            (this.width / 2) - (int) (24 * SMALL_SIGN_SIZE * 0.5) + (int) (24 * SMALL_SIGN_SIZE * 1.5),
+            (int) (1.0625f * 93.75f) + yOffset + 5,
+            mx, my,
+            block, this.entitySign.getBlockMeta(),
+            nextPicture
+        );
 
         super.render(mx, my, partialTick);
     }
 
+    private void drawFakeSign(final int x, final int y, final int mx, final int my, final @NotNull Block<?> block, final int meta, final @NotNull EnumSignPicture picture) {
+        // Fetch and bind base texture
+        final int colorSign;
+        if (Block.hasLogicClass(block, BlockLogicSignPainted.class)) {
+            final @NotNull DyeColor c = ((IPainted) block.getLogic()).fromMetadata(meta);
+            this.mc.textureManager.loadTexture("/assets/minecraft/textures/entity/sign/" + c.colorID + ".png").bind();
+            colorSign = c.color.getARGB();
+        } else {
+            this.mc.textureManager.loadTexture("/assets/minecraft/textures/entity/sign.png").bind();
+            colorSign = 0x877756;
+        }
+
+        final boolean mouseOver = mx >= x && mx <= x + 24 * SMALL_SIGN_SIZE && my >= y && (my <= y + 12 * SMALL_SIGN_SIZE);
+
+        GLRenderer.pushFrame();
+        if (!mouseOver) {
+            GLRenderer.setColor4f(0.75f, 0.75f, 0.75f, 1.0f);
+        } else {
+            GLRenderer.setColor4f(1.0f, 1.0f, 1.0f, 1.0f);
+        }
+
+        // Render base texture
+        this.drawTexturedModalRectDouble(x, y, 2 * SMALL_SIGN_SIZE, 2 * SMALL_SIGN_SIZE, 24 * SMALL_SIGN_SIZE, 12 * SMALL_SIGN_SIZE, 1.0 / (64.0 * SMALL_SIGN_SIZE), 1.0 / (32.0 * SMALL_SIGN_SIZE));
+
+        // Render overlay texture
+        if (picture != EnumSignPicture.NONE) {
+            GLRenderer.enableState(State.BLEND);
+            GLRenderer.setBlendFunc(BlendFactor.ZERO, BlendFactor.SRC_COLOR);
+            GLRenderer.setDepthMask(false);
+            drawTexturedModalRect(x, y, 24 * SMALL_SIGN_SIZE, 12 * SMALL_SIGN_SIZE, colorSign, TextureRegistry.getTexture(picture.getTextureKey()));
+            GLRenderer.disableState(State.BLEND);
+        }
+
+        GLRenderer.setColor4f(1.0f, 1.0f, 1.0f, 1.0f);
+        GLRenderer.popFrame();
+    }
+
+    private static void drawTexturedModalRect(final double x, final double y, final double width, final double height, final int color, final @NotNull IconCoordinate coordinate) {
+        coordinate.parentAtlas.bind();
+        final TessellatorGeneral tessellator = GLRenderer.getTessellator();
+        tessellator.startDrawingQuads();
+        tessellator.setColor2i(0xffffff, 64);
+        tessellator.addVertexWithUV(x, y + height, 0, coordinate.getIconUMin(), coordinate.getIconVMax());
+        tessellator.addVertexWithUV(x, y, 0, coordinate.getIconUMin(), coordinate.getIconVMin());
+        tessellator.addVertexWithUV(x + width, y, 0, coordinate.getIconUMax(), coordinate.getIconVMin());
+        tessellator.addVertexWithUV(x + width, y + height, 0, coordinate.getIconUMax(), coordinate.getIconVMax());
+        tessellator.draw();
+    }
+
     @Override
-    public void guiSpecificControllerInput(@NotNull ControllerInput controller) {
+    public void guiSpecificControllerInput(@NotNull final ControllerInput controller) {
         super.guiSpecificControllerInput(controller);
         if (controller.digitalPad.up.pressedThisFrame()) {
             this.editLine = this.editLine - 1 & 3;
@@ -209,15 +396,4 @@ public class ScreenSignEditor extends Screen {
             this.editLine = this.editLine + 1 & 3;
         }
     }
-
-    protected String screenTitle;
-    private final @NotNull TileEntitySign entitySign;
-    private int updateCounter;
-    private int editLine;
-    private int yOffset = 0;
-    private static final String allowedCharacters;
-
-    static {
-        allowedCharacters = ChatAllowedCharacters.ALLOWED_CHARACTERS;
-    }
 }
diff --git a/game/client/src/main/java/net/minecraft/client/gui/modelviewer/elements/ListenerButtonElement.java b/game/client/src/main/java/net/minecraft/client/gui/modelviewer/elements/ListenerButtonElement.java
index 4c26e2401..5a8c5f2e7 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/modelviewer/elements/ListenerButtonElement.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/modelviewer/elements/ListenerButtonElement.java
@@ -2,6 +2,8 @@ package net.minecraft.client.gui.modelviewer.elements;
 
 import net.minecraft.client.Minecraft;
 import net.minecraft.client.gui.ButtonElement;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
 
 public class ListenerButtonElement extends ButtonElement implements IListenerElement<ListenerButtonElement> {
     protected IActionListener action;
@@ -29,7 +31,7 @@ public class ListenerButtonElement extends ButtonElement implements IListenerEle
         }
     }
     @Override
-    public ListenerButtonElement setActionListener(IActionListener listener) {
+    public @NotNull ListenerButtonElement setActionListener(@Nullable IActionListener listener) {
         action = listener;
         return this;
     }
diff --git a/game/client/src/main/java/net/minecraft/client/render/tileentity/TileEntityRendererSign.java b/game/client/src/main/java/net/minecraft/client/render/tileentity/TileEntityRendererSign.java
index 18ba368f6..9dc06ca8c 100644
--- a/game/client/src/main/java/net/minecraft/client/render/tileentity/TileEntityRendererSign.java
+++ b/game/client/src/main/java/net/minecraft/client/render/tileentity/TileEntityRendererSign.java
@@ -7,6 +7,7 @@ import net.minecraft.client.render.camera.ICamera;
 import net.minecraft.client.render.font.Font;
 import net.minecraft.client.render.font.FontRendererDefault;
 import net.minecraft.client.render.font.SF;
+import net.minecraft.client.render.renderer.BlendFactor;
 import net.minecraft.client.render.renderer.GLRenderer;
 import net.minecraft.client.render.renderer.State;
 import net.minecraft.client.render.tessellator.TessellatorFont;
@@ -92,8 +93,7 @@ public class TileEntityRendererSign extends TileEntityRenderer<TileEntitySign> {
             colorSign = c.color.getARGB();
         } else {
             bindTexture("/assets/minecraft/textures/entity/sign.png");
-//            colorSign = 0xa57319;
-            colorSign = 0x695e43;
+            colorSign = 0x877756;
         }
         GLRenderer.disableState(State.BLEND);
         model.render();
@@ -106,9 +106,11 @@ public class TileEntityRendererSign extends TileEntityRenderer<TileEntitySign> {
         GLRenderer.modelM4f().translate(0 * scale, height * scale, 1.05f * scale);
         GLRenderer.setDepthMask(false);
         GLRenderer.setColor4f(1, 1, 1, 1);
+        GLRenderer.setBlendFunc(BlendFactor.ZERO, BlendFactor.SRC_COLOR);
         final EnumSignPicture picture = tileEntity.getPicture();
-        if (picture != EnumSignPicture.NONE)
+        if (picture != EnumSignPicture.NONE) {
             drawTexturedModalRect(1, 0.5, colorSign, TextureRegistry.getTexture(picture.getTextureKey()));
+        }
         GLRenderer.disableState(State.BLEND);
         GLRenderer.popFrame();
 
@@ -169,15 +171,17 @@ public class TileEntityRendererSign extends TileEntityRenderer<TileEntitySign> {
     }
 
     private static void drawTexturedModalRect(final double width, final double height, final int color, final @NotNull IconCoordinate coordinate) {
+        GLRenderer.globalSetLightEnabled(false);
         coordinate.parentAtlas.bind();
         final TessellatorGeneral tessellator = GLRenderer.getTessellator();
         tessellator.startDrawingQuads();
-        tessellator.setColor2i(color, 128);
+        tessellator.setColor2i(0xffffff, 64);
         tessellator.addVertexWithUV(-width / 2, height / 2, 0, coordinate.getIconUMin(), coordinate.getIconVMin());
         tessellator.addVertexWithUV(-width / 2, -height / 2, 0, coordinate.getIconUMin(), coordinate.getIconVMax());
         tessellator.addVertexWithUV(width / 2, -height / 2, 0, coordinate.getIconUMax(), coordinate.getIconVMax());
         tessellator.addVertexWithUV(width / 2, height / 2, 0, coordinate.getIconUMax(), coordinate.getIconVMin());
         tessellator.draw();
+        GLRenderer.globalSetLightEnabled(true);
     }
 
     @Override
diff --git a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/afk.png b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/afk.png
index afc0d24b0..1aa169e82 100644
Binary files a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/afk.png and b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/afk.png differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/arrow_down.png b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/arrow_down.png
index cea63a243..f9b08c0d9 100644
Binary files a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/arrow_down.png and b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/arrow_down.png differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/arrow_left.png b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/arrow_left.png
index 88bac6d03..68d980628 100644
Binary files a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/arrow_left.png and b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/arrow_left.png differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/arrow_right.png b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/arrow_right.png
index 21e81ee65..26d1e41a9 100644
Binary files a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/arrow_right.png and b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/arrow_right.png differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/arrow_up.png b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/arrow_up.png
index 8fb73acab..47bd6da0b 100644
Binary files a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/arrow_up.png and b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/arrow_up.png differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/arrows_left_right.png b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/arrows_left_right.png
index 5ac81b2c1..d1607d216 100644
Binary files a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/arrows_left_right.png and b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/arrows_left_right.png differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/arrows_up_down.png b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/arrows_up_down.png
index e2f54c2a1..7fd205a4e 100644
Binary files a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/arrows_up_down.png and b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/arrows_up_down.png differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/axe.png b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/axe.png
index 855038c76..a609d3cec 100644
Binary files a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/axe.png and b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/axe.png differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/barricade.png b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/barricade.png
index 73145a44a..e9d131592 100644
Binary files a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/barricade.png and b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/barricade.png differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/big_sign.png b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/big_sign.png
index ff9d45ab3..65dc37601 100644
Binary files a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/big_sign.png and b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/big_sign.png differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/bowl.png b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/bowl.png
index a9dac9ac9..4d5c7a8a2 100644
Binary files a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/bowl.png and b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/bowl.png differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/brb.png b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/brb.png
index cc7c0cec4..d71798ce0 100644
Binary files a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/brb.png and b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/brb.png differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/caution.png b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/caution.png
index 33a84a512..e0de1ba0d 100644
Binary files a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/caution.png and b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/caution.png differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/check.png b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/check.png
index baa769a30..bf1d29641 100644
Binary files a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/check.png and b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/check.png differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/chest.png b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/chest.png
index 0f9264bfc..6e9281122 100644
Binary files a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/chest.png and b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/chest.png differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/craft.png b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/craft.png
index 15cfdcd7e..9216b683e 100644
Binary files a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/craft.png and b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/craft.png differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/cross.png b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/cross.png
index 1c4008ce3..6ad7fda2e 100644
Binary files a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/cross.png and b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/cross.png differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/exit.png b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/exit.png
index dfd50e291..da2ad5f32 100644
Binary files a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/exit.png and b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/exit.png differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/face_confused.png b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/face_confused.png
index 286bcae2f..fdac5e839 100644
Binary files a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/face_confused.png and b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/face_confused.png differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/face_crying.png b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/face_crying.png
index d4f86b11e..a8235908a 100644
Binary files a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/face_crying.png and b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/face_crying.png differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/face_gasp.png b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/face_gasp.png
index 1efb13c77..7bf2613b7 100644
Binary files a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/face_gasp.png and b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/face_gasp.png differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/face_sad.png b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/face_sad.png
index 6d8c64690..c755bb96e 100644
Binary files a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/face_sad.png and b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/face_sad.png differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/face_smile.png b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/face_smile.png
index 7160c6224..668ab5ebc 100644
Binary files a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/face_smile.png and b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/face_smile.png differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/face_thinking.png b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/face_thinking.png
index 7036ba809..17ab6d797 100644
Binary files a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/face_thinking.png and b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/face_thinking.png differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/farm.png b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/farm.png
index f800a3d86..4fa8b1cd7 100644
Binary files a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/farm.png and b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/farm.png differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/heart.png b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/heart.png
index b428e7ed3..d351d85a8 100644
Binary files a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/heart.png and b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/heart.png differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/hoe.png b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/hoe.png
index 0febb1d9d..6bc947396 100644
Binary files a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/hoe.png and b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/hoe.png differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/mine.png b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/mine.png
index 174999d5b..3c346733c 100644
Binary files a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/mine.png and b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/mine.png differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/mob_creeper.png b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/mob_creeper.png
index 724655e79..87ae578f5 100644
Binary files a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/mob_creeper.png and b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/mob_creeper.png differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/mob_farm.png b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/mob_farm.png
index f5ed89e9f..728de5360 100644
Binary files a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/mob_farm.png and b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/mob_farm.png differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/mob_skeleton.png b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/mob_skeleton.png
index 022badc37..139b49774 100644
Binary files a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/mob_skeleton.png and b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/mob_skeleton.png differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/mob_zombie.png b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/mob_zombie.png
index dfd33ceec..31066cbfd 100644
Binary files a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/mob_zombie.png and b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/mob_zombie.png differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/mobs.png b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/mobs.png
index 7fd8c0b68..ac52e7504 100644
Binary files a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/mobs.png and b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/mobs.png differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/one_player.png b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/one_player.png
index 01d445481..837171224 100644
Binary files a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/one_player.png and b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/one_player.png differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/pickaxe.png b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/pickaxe.png
index e45507249..4816903e7 100644
Binary files a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/pickaxe.png and b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/pickaxe.png differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/question_mark.png b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/question_mark.png
index 4cbfeafff..b72148b92 100644
Binary files a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/question_mark.png and b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/question_mark.png differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/redstone.png b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/redstone.png
index de572e9e1..364fc3dea 100644
Binary files a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/redstone.png and b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/redstone.png differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/shovel.png b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/shovel.png
index 8ffd74c9e..f7b3414d3 100644
Binary files a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/shovel.png and b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/shovel.png differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/sword.png b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/sword.png
index 39b87d0bd..5923d3a98 100644
Binary files a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/sword.png and b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/sword.png differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/three_players.png b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/three_players.png
index e20a8921c..cc06c3bb8 100644
Binary files a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/three_players.png and b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/three_players.png differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/tnt.png b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/tnt.png
index d045c0d82..36d6a285e 100644
Binary files a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/tnt.png and b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/tnt.png differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/trees.png b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/trees.png
index 45e1f0864..95eba8a47 100644
Binary files a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/trees.png and b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/trees.png differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/two_players.png b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/two_players.png
index d3f54db64..3b55777df 100644
Binary files a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/two_players.png and b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/two_players.png differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/wolf.png b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/wolf.png
index 1bf31f044..f9868da4b 100644
Binary files a/game/client/src/main/resources/assets/minecraft/textures/gui/sign/wolf.png and b/game/client/src/main/resources/assets/minecraft/textures/gui/sign/wolf.png differ
diff --git a/game/core/.gitignore b/game/core/.gitignore
index 378eac25d..54f46fc3d 100644
--- a/game/core/.gitignore
+++ b/game/core/.gitignore
@@ -1 +1,2 @@
 build
+out
\ No newline at end of file
diff --git a/game/core/src/main/java/net/minecraft/core/block/entity/TileEntity.java b/game/core/src/main/java/net/minecraft/core/block/entity/TileEntity.java
index 44c9fa74e..c2ec0bd7b 100644
--- a/game/core/src/main/java/net/minecraft/core/block/entity/TileEntity.java
+++ b/game/core/src/main/java/net/minecraft/core/block/entity/TileEntity.java
@@ -62,7 +62,7 @@ public abstract class TileEntity implements ICarriable
         }
     }
 
-    public Block<?> getBlock() {
+    public @NotNull Block<?> getBlock() {
         if (carriedBlock != null) {
             return carriedBlock.block();
         } else {
diff --git a/game/core/src/main/java/net/minecraft/core/block/entity/TileEntitySign.java b/game/core/src/main/java/net/minecraft/core/block/entity/TileEntitySign.java
index 88d956cb6..b1a5c079d 100644
--- a/game/core/src/main/java/net/minecraft/core/block/entity/TileEntitySign.java
+++ b/game/core/src/main/java/net/minecraft/core/block/entity/TileEntitySign.java
@@ -15,7 +15,7 @@ import java.util.UUID;
 public class TileEntitySign extends TileEntity
 {
     public static final int MAX_LINE_SIZE = 15;
-    public String[] signText = { "", "", "", "" };
+    public @NotNull String @NotNull [] signText = { "", "", "", "" };
     public int lineBeingEdited;
     private int selectedPicture = 0;
     private int selectedColor = 15;
@@ -85,7 +85,7 @@ public class TileEntitySign extends TileEntity
         return EnumSignPicture.fromId(selectedPicture);
     }
 
-    public void setPicture(EnumSignPicture picture)
+    public void setPicture(@Nullable EnumSignPicture picture)
     {
         if (picture == null)
         {
diff --git a/game/core/src/main/java/net/minecraft/core/enums/EnumSignPicture.java b/game/core/src/main/java/net/minecraft/core/enums/EnumSignPicture.java
index 0b33796b0..ce00534e8 100644
--- a/game/core/src/main/java/net/minecraft/core/enums/EnumSignPicture.java
+++ b/game/core/src/main/java/net/minecraft/core/enums/EnumSignPicture.java
@@ -1,5 +1,6 @@
 package net.minecraft.core.enums;
 
+import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
 public enum EnumSignPicture
@@ -52,10 +53,10 @@ public enum EnumSignPicture
 
     private static EnumSignPicture[] vals = values();
     private final int id;
-    private final String languageKey;
-    private final String texKey;
+    private final @NotNull String languageKey;
+    private final @NotNull String texKey;
 
-    EnumSignPicture(int id, String languageKey, String textureKey)
+    EnumSignPicture(int id, @NotNull String languageKey, @NotNull String textureKey)
     {
         this.id = id;
         this.languageKey = languageKey;
@@ -67,12 +68,12 @@ public enum EnumSignPicture
         return id;
     }
 
-    public String getLanguageKey()
+    public @NotNull String getLanguageKey()
     {
         return languageKey;
     }
 
-    public String getTextureKey()
+    public @NotNull String getTextureKey()
     {
         return texKey;
     }
diff --git a/game/core/src/main/java/net/minecraft/core/util/Nullability.java b/game/core/src/main/java/net/minecraft/core/util/Nullability.java
new file mode 100644
index 000000000..cda48c96b
--- /dev/null
+++ b/game/core/src/main/java/net/minecraft/core/util/Nullability.java
@@ -0,0 +1,41 @@
+package net.minecraft.core.util;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.function.Function;
+import java.util.function.Supplier;
+
+public abstract class Nullability {
+    public static <T> @NotNull T unwrapOr(final @Nullable T value, final @NotNull T or) {
+        if (value == null) {
+            return or;
+        }
+
+        return value;
+    }
+
+    public static <T> @NotNull T unwrapOrElse(final @Nullable T value, final @NotNull Supplier<@NotNull T> or) {
+        if (value == null) {
+            return or.get();
+        }
+
+        return value;
+    }
+
+    public static <T, E> @Nullable E map(final @Nullable T value, final @NotNull Function<@NotNull T, @NotNull E> map) {
+        if (value != null) {
+            return map.apply(value);
+        }
+
+        return null;
+    }
+
+    public static <T, E> @NotNull E mapOr(final @Nullable T value, final @NotNull E or, final @NotNull Function<@NotNull T, @NotNull E> map) {
+        if (value != null) {
+            return map.apply(value);
+        }
+
+        return or;
+    }
+}
diff --git a/game/server/.gitignore b/game/server/.gitignore
index 8219306d0..bcef4dac8 100644
--- a/game/server/.gitignore
+++ b/game/server/.gitignore
@@ -1,3 +1,4 @@
 build
 mp
-logs
\ No newline at end of file
+logs
+out
\ No newline at end of file
diff --git a/util/datagen/.gitignore b/util/datagen/.gitignore
index 2959db291..d232169b9 100644
--- a/util/datagen/.gitignore
+++ b/util/datagen/.gitignore
@@ -1,2 +1,3 @@
 build
-logs
\ No newline at end of file
+logs
+out
\ No newline at end of file
diff --git a/util/logging/.gitignore b/util/logging/.gitignore
index c795b054e..54f46fc3d 100644
--- a/util/logging/.gitignore
+++ b/util/logging/.gitignore
@@ -1 +1,2 @@
-build
\ No newline at end of file
+build
+out
\ No newline at end of file
diff --git a/util/nbt/.gitignore b/util/nbt/.gitignore
index 6ca7a5037..8b7f80925 100644
--- a/util/nbt/.gitignore
+++ b/util/nbt/.gitignore
@@ -1,2 +1,3 @@
 build
-testWork
\ No newline at end of file
+testWork
+out
\ No newline at end of file
diff --git a/util/seed-viewer/.gitignore b/util/seed-viewer/.gitignore
index 2959db291..d232169b9 100644
--- a/util/seed-viewer/.gitignore
+++ b/util/seed-viewer/.gitignore
@@ -1,2 +1,3 @@
 build
-logs
\ No newline at end of file
+logs
+out
\ No newline at end of file
diff --git a/util/stellar/.gitignore b/util/stellar/.gitignore
index 2959db291..d232169b9 100644
--- a/util/stellar/.gitignore
+++ b/util/stellar/.gitignore
@@ -1,2 +1,3 @@
 build
-logs
\ No newline at end of file
+logs
+out
\ No newline at end of file
