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 6f50c6fa1..6241e6b16 100644
--- a/game/client/src/main/java/net/minecraft/client/Minecraft.java
+++ b/game/client/src/main/java/net/minecraft/client/Minecraft.java
@@ -2292,6 +2292,7 @@ public class Minecraft
                 null
         );
         world.getLevelData().setCheatsEnabled(worldConfiguration.getCheatsEnabled());
+        world.getLevelData().getGameRules().setValues(worldConfiguration.getGameRuleCollection());
 
         this.statsCounter.add(StatList.createWorldStat, 1);
         this.statsCounter.add(StatList.startGameStat, 1);
diff --git a/game/client/src/main/java/net/minecraft/client/gui/ScreenCreateWorld.java b/game/client/src/main/java/net/minecraft/client/gui/ScreenCreateWorld.java
index 36795cfd2..08a853f00 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/ScreenCreateWorld.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/ScreenCreateWorld.java
@@ -2,9 +2,8 @@ package net.minecraft.client.gui;
 
 import net.minecraft.client.gui.popup.PopupScreen;
 import net.minecraft.client.gui.popup.PopupBuilder;
-import net.minecraft.client.player.controller.PlayerControllerSP;
+import net.minecraft.client.gui.worldsettings.ScreenWorldSettings;
 import net.minecraft.core.data.registry.Registries;
-import net.minecraft.core.item.Items;
 import net.minecraft.core.lang.I18n;
 import net.minecraft.core.net.command.TextFormatting;
 import net.minecraft.core.player.gamemode.Gamemode;
@@ -24,7 +23,7 @@ public class ScreenCreateWorld extends Screen {
     private ButtonElement createWorldButton;
     private ButtonElement gamemodeButton;
     private ButtonElement cheatsButton;
-    private ButtonElement worldTypeButton;
+    private ButtonElement worldSettingsButton;
     private ButtonElement buttonRandomWorldName;
     private ButtonElement buttonRandomSeed;
     private boolean createClicked;
@@ -55,7 +54,7 @@ public class ScreenCreateWorld extends Screen {
         textboxSeed = new TextFieldElement(this, fontRenderer, width / 2 - 100, 100, 200 - 24, 20, "", Long.toString(this.worldConfiguration.getNumericSeed()));
         buttons.add(gamemodeButton = new ButtonElement(2, width / 2 - 100, 100 + 20 + 4, 98, 20, ""));
         buttons.add(cheatsButton = new ButtonElement(3, width / 2 - 100 + 102, 100 + 20 + 4, 98, 20, ""));
-        buttons.add(worldTypeButton = new ButtonElement(4, width / 2 - 100, 100 + 20 + 20 + 4 + 4, ""));
+        buttons.add(worldSettingsButton = new ButtonElement(4, width / 2 - 100, 100 + 20 + 20 + 4 + 4, i18n.translateKey("gui.create_world.button.world_settings")));
         buttons.add(buttonRandomWorldName = new ButtonElement(5, width / 2 + 100 - 20, 60, 20, 20, "")
                 .setTextures("minecraft:gui/misc/button_random", "minecraft:gui/misc/button_random_highlighted", "minecraft:gui/misc/button_random"));
         buttons.add(buttonRandomSeed = new ButtonElement(6, width / 2 + 100 - 20, 100, 20, 20, "")
@@ -93,29 +92,8 @@ public class ScreenCreateWorld extends Screen {
         } else if (button == cheatsButton) {
             this.worldConfiguration.setCheatsEnabled(!this.worldConfiguration.getCheatsEnabled());
             syncButtons();
-        } else if (button == worldTypeButton) {
-            I18n i18n = I18n.getInstance();
-            String[] keys = new String[WorldTypeGroups.GROUPS.size()];
-            String[] descs = new String[WorldTypeGroups.GROUPS.size()];
-            for (int i = 0; i < keys.length; i++) {
-                keys[i] = i18n.translateKey(WorldTypeGroups.GROUPS.get(i).get(Dimension.OVERWORLD).getLanguageKey() + ".name");
-                descs[i] = i18n.translateKey(WorldTypeGroups.GROUPS.get(i).get(Dimension.OVERWORLD).getLanguageKey() + ".desc") + "\n" +
-                        TextFormatting.GRAY + Registries.WORLD_TYPES.getKey(WorldTypeGroups.GROUPS.get(i).get(Dimension.OVERWORLD));
-            }
-
-            PopupScreen popup = new PopupBuilder(this, 150)
-                    .closeOnEsc(0)
-                    .closeOnClickOut(0)
-                    .withLabel("gui.create_world.label.select_world_type")
-                    .withList("worldTypeList", 140, keys, descs, WorldTypeGroups.GROUPS.indexOf(this.worldConfiguration.getWorldTypeGroup()), true)
-                    .withOnCloseListener((statusCode, results) -> {
-                        if (statusCode == 1) {
-                            this.worldConfiguration.setWorldTypeGroup(WorldTypeGroups.GROUPS.get((Integer) results.get("worldTypeList")));
-                            syncButtons();
-                        }
-                    })
-                    .build();
-            mc.displayScreen(popup);
+        } else if (button == worldSettingsButton) {
+            mc.displayScreen(new ScreenWorldSettings(this, this.worldConfiguration));
         } else if (button == buttonRandomWorldName) {
             textboxWorldName.setText(I18n.getInstance().getCurrentLanguage().getRandomWorldName());
             syncConfig();
@@ -133,7 +111,6 @@ public class ScreenCreateWorld extends Screen {
         this.textboxSeed.setText(this.worldConfiguration.getStringSeed());
         gamemodeButton.displayString = i18n.translateKeyAndFormat("gui.create_world.button.gamemode", i18n.translateKey(this.worldConfiguration.getGamemode().getLanguageKey() + ".name"));
         cheatsButton.displayString = i18n.translateKeyAndFormat("gui.create_world.button.cheats", i18n.translateKey(this.worldConfiguration.getCheatsEnabled() ? "gui.create_world.button.cheats.on" : "gui.create_world.button.cheats.off"));
-        worldTypeButton.displayString = i18n.translateKeyAndFormat("gui.create_world.button.world_type", i18n.translateKey(this.worldConfiguration.getWorldTypeGroup().get(Dimension.OVERWORLD).getLanguageKey() + ".name"));
     }
 
     private void syncConfig() {
diff --git a/game/client/src/main/java/net/minecraft/client/gui/ScreenSelectWorld.java b/game/client/src/main/java/net/minecraft/client/gui/ScreenSelectWorld.java
index 1a55fed5e..6395aaa4a 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/ScreenSelectWorld.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/ScreenSelectWorld.java
@@ -3,6 +3,7 @@ package net.minecraft.client.gui;
 import com.mojang.nbt.tags.CompoundTag;
 import net.minecraft.client.gui.popup.PopupScreen;
 import net.minecraft.client.gui.popup.PopupBuilder;
+import net.minecraft.client.gui.worldsettings.ScreenWorldSettings;
 import net.minecraft.client.render.tessellator.Tessellator;
 import net.minecraft.core.Global;
 import net.minecraft.core.net.command.TextFormatting;
diff --git a/game/client/src/main/java/net/minecraft/client/gui/options/components/DifficultyOptionComponent.java b/game/client/src/main/java/net/minecraft/client/gui/options/components/DifficultyOptionComponent.java
index 638434761..64ef2a28c 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/options/components/DifficultyOptionComponent.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/options/components/DifficultyOptionComponent.java
@@ -3,10 +3,12 @@ package net.minecraft.client.gui.options.components;
 import net.minecraft.client.Minecraft;
 import net.minecraft.client.gui.ButtonElement;
 import net.minecraft.client.gui.IntegerSliderElement;
+import net.minecraft.client.gui.popup.PopupBuilder;
 import net.minecraft.client.option.OptionEnum;
 import net.minecraft.client.render.window.CursorShape;
 import net.minecraft.core.enums.Difficulty;
 import net.minecraft.core.lang.I18n;
+import net.minecraft.core.net.command.TextFormatting;
 import org.jetbrains.annotations.Nullable;
 
 public class DifficultyOptionComponent extends ButtonComponent {
@@ -34,7 +36,20 @@ public class DifficultyOptionComponent extends ButtonComponent {
         onChanged();
         this.option.onUpdate();
         if (mc.currentWorld != null && this.lockButton.mouseClicked(mc, this.slider.xPosition + relativeMouseX, this.slider.yPosition + relativeMouseY)) {
-            mc.currentWorld.getLevelData().setDifficultyLocked();
+            mc.displayScreen(new PopupBuilder(mc.currentScreen, 160)
+                    .withLabel("gui.options.difficultylock.warning.1")
+                    .withLabel("gui.options.difficultylock.warning.2")
+                    .withLabel("gui.options.difficultylock.warning.3", 0xFF0000)
+                    .withButtonGroup("2", new String[]{"gui.options.difficultylock.button.yes", "gui.options.difficultylock.button.no"}, new int[]{1, 0})
+                    .closeOnClickOut(0)
+                    .closeOnEnter(1)
+                    .closeOnEsc(0)
+                    .withOnCloseListener((statusCode, results) -> {
+                        if (statusCode == 1) {
+                            mc.currentWorld.getLevelData().setDifficultyLocked();
+                        }
+                    })
+                .build());
         }
     }
 
@@ -93,7 +108,10 @@ public class DifficultyOptionComponent extends ButtonComponent {
     @Override
     public void resetValue() {
         if (canSetDifficulty()) {
-            mc.currentWorld.setDifficulty(Difficulty.NORMAL, false);
+            option.set(Difficulty.NORMAL);
+            slider.sliderValue = option.value.id();
+            mc.currentWorld.setDifficulty(Difficulty.NORMAL, true);
+            onChanged();
         }
     }
 
diff --git a/game/client/src/main/java/net/minecraft/client/gui/paged/ScreenPaged.java b/game/client/src/main/java/net/minecraft/client/gui/paged/ScreenPaged.java
index 65c256665..c1ebf91fb 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/paged/ScreenPaged.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/paged/ScreenPaged.java
@@ -42,7 +42,11 @@ public class ScreenPaged
     {
         super(parent);
         this.pageRegistry = pageRegistry;
-        this.selectedPage = selectedPage;
+        if (selectedPage == null) {
+            this.selectedPage = pageRegistry.getPages().get(0);
+        } else {
+            this.selectedPage = selectedPage;
+        }
         this.titleTranslationKey = titleTranslationKey;
         this.buttonTranslationKeys = buttonTranslationKeys;
     }
diff --git a/game/client/src/main/java/net/minecraft/client/gui/worldsettings/BooleanGameRuleComponent.java b/game/client/src/main/java/net/minecraft/client/gui/worldsettings/BooleanGameRuleComponent.java
new file mode 100644
index 000000000..1fb8f6580
--- /dev/null
+++ b/game/client/src/main/java/net/minecraft/client/gui/worldsettings/BooleanGameRuleComponent.java
@@ -0,0 +1,75 @@
+package net.minecraft.client.gui.worldsettings;
+
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.SwitchElement;
+import net.minecraft.client.render.window.CursorShape;
+import net.minecraft.core.data.gamerule.GameRuleBoolean;
+import net.minecraft.core.data.gamerule.GameRuleCollection;
+import net.minecraft.core.lang.I18n;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+public class BooleanGameRuleComponent
+    extends ButtonComponent
+{
+    private @Nullable GameRuleCollection gameRuleCollection = null;
+    private final GameRuleBoolean gameRule;
+    private final SwitchElement button;
+
+    public BooleanGameRuleComponent(GameRuleBoolean gameRule)
+    {
+        super(gameRule.getTranslationKey() + ".name", gameRule.getTranslationKey() + ".desc");
+
+        this.gameRule = gameRule;
+        this.button = new SwitchElement(0, 0, 0, 150, 20, this.gameRule.getDefaultValue(), I18n.getInstance().translateKey("gui.world_settings.page.game_rules.button.on"), I18n.getInstance().translateKey("gui.world_settings.page.game_rules.button.off"));
+        this.button.setOn(this.gameRule.getDefaultValue());
+    }
+
+    public void setGameRuleCollection(final @NotNull GameRuleCollection collection) {
+        this.gameRuleCollection = collection;
+    }
+
+    @Override
+    public void resetValue() {
+        gameRuleCollection.setValue(this.gameRule, this.gameRule.getDefaultValue());
+        onChange();
+    }
+
+    @Override
+    public void init(Minecraft mc){
+        onChange();
+    }
+
+    @Override
+    public boolean isDefault() {
+        return gameRuleCollection.getValue(this.gameRule).equals(gameRule.getDefaultValue());
+    }
+
+    @Override
+    protected void buttonClicked(int mouseButton, int x, int y, int width, int height, int relativeMouseX, int relativeMouseY)
+    {
+        gameRuleCollection.setValue(this.gameRule, !this.gameRuleCollection.getValue(this.gameRule));
+        onChange();
+    }
+
+    protected void onChange() {
+        this.button.setOn(this.gameRuleCollection.getValue(this.gameRule));
+    }
+
+    @Override
+    protected void renderButton(int x, int y, int relativeButtonX, int relativeButtonY, int buttonWidth, int buttonHeight, int relativeMouseX, int relativeMouseY)
+    {
+        super.renderButton(x, y, relativeButtonX, relativeButtonY, buttonWidth, buttonHeight, relativeMouseX, relativeMouseY);
+
+        this.button.xPosition = x + relativeButtonX;
+        this.button.yPosition = y + relativeButtonY;
+        this.button.width = buttonWidth;
+        this.button.height = buttonHeight;
+
+        this.button.drawButton(mc, x + relativeMouseX, y + relativeMouseY);
+
+        if (relativeMouseX >= relativeButtonX && relativeMouseX < relativeButtonX + buttonWidth && relativeMouseY >= relativeButtonY && relativeButtonY < relativeButtonY + buttonHeight) {
+            mc.currentScreen.setDesiredCursor(CursorShape.HAND);
+        }
+    }
+}
diff --git a/game/client/src/main/java/net/minecraft/client/gui/worldsettings/ButtonComponent.java b/game/client/src/main/java/net/minecraft/client/gui/worldsettings/ButtonComponent.java
new file mode 100644
index 000000000..654639ba5
--- /dev/null
+++ b/game/client/src/main/java/net/minecraft/client/gui/worldsettings/ButtonComponent.java
@@ -0,0 +1,140 @@
+package net.minecraft.client.gui.worldsettings;
+
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.ButtonElement;
+import net.minecraft.client.gui.paged.PageComponent;
+import net.minecraft.client.render.tessellator.Tessellator;
+import net.minecraft.client.render.window.CursorShape;
+import net.minecraft.core.lang.I18n;
+import net.minecraft.core.sound.SoundCategory;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.lwjgl.opengl.GL11;
+
+import static org.lwjgl.opengl.GL11.*;
+import static org.lwjgl.opengl.GL11.GL_BLEND;
+
+public abstract class ButtonComponent
+    implements PageComponent
+{
+    protected static final Minecraft mc = Minecraft.getMinecraft();
+    protected static final int COMPONENT_SPACING = 2;
+    private static final int BUTTON_WIDTH = 100;
+
+    private final @NotNull String translationKey;
+    private final @Nullable String tooltipTranslationKey;
+
+    protected final ButtonElement resetButton;
+
+    private boolean hovered = false;
+
+    public ButtonComponent(@NotNull String translationKey, @Nullable String tooltipTranslationKey)
+    {
+        this.translationKey = translationKey;
+        this.tooltipTranslationKey = tooltipTranslationKey;
+        this.resetButton = new ButtonElement(0, 0, 0, 20, 20, "")
+                .setTextures("minecraft:gui/misc/icon_reset", "minecraft:gui/misc/icon_reset_highlighted", "minecraft:gui/misc/icon_reset");
+    }
+
+    public abstract void resetValue();
+
+    public abstract boolean isDefault();
+
+    @Override
+    public int getHeight()
+    {
+        return COMPONENT_SPACING + 20 + COMPONENT_SPACING;
+    }
+
+    @Override
+    public void render(int x, int y, int width, int relativeMouseX, int relativeMouseY)
+    {
+        String translated = I18n.getInstance().translateKey(translationKey);
+        int textColor = 0xFFFFFFFF;
+        if (relativeMouseX >= 0 && relativeMouseX <= width && relativeMouseY >= COMPONENT_SPACING && relativeMouseY <= getHeight() - COMPONENT_SPACING) {
+            textColor = 0xFFFFFFA0;
+        }
+
+        if (relativeMouseX >= 0 && relativeMouseX <= width - BUTTON_WIDTH && relativeMouseY >= COMPONENT_SPACING && relativeMouseY <= getHeight() - COMPONENT_SPACING) {
+            this.hovered = true;
+        } else {
+            this.hovered = false;
+        }
+
+        mc.font.render(Tessellator.instance, translated, x, y + (getHeight() / 2) - 4).setShadow().setColor(textColor).call();
+        resetButton.enabled = !isDefault();
+        renderButton(x, y, width - BUTTON_WIDTH, COMPONENT_SPACING, BUTTON_WIDTH, 20, relativeMouseX, relativeMouseY);
+        int stringWidth = mc.font.stringWidth(translated);
+        int lineMaxX = x + width - BUTTON_WIDTH - 8;
+        if (resetButton.enabled) lineMaxX -= 20;
+        drawRect(x + stringWidth + 8, y + getHeight() / 2, lineMaxX, y + getHeight() / 2 + 1, 0x5F7F7F7F);
+    }
+
+    @Override
+    public void onMouseClick(int mouseButton, int x, int y, int width, int relativeMouseX, int relativeMouseY)
+    {
+        if (relativeMouseX >= width - BUTTON_WIDTH && relativeMouseX <= width && relativeMouseY >= COMPONENT_SPACING && relativeMouseY <= COMPONENT_SPACING + 20) {
+            mc.sndManager.playSound("random.click", SoundCategory.GUI_SOUNDS, 1.0F, 1.0F);
+            buttonClicked(mouseButton, x, y, width, getHeight(), relativeMouseX - (width - BUTTON_WIDTH), relativeMouseY - COMPONENT_SPACING);
+        } else if (resetButton.enabled && relativeMouseX >= width - BUTTON_WIDTH - 20 && relativeMouseX <= width - BUTTON_WIDTH && relativeMouseY >= COMPONENT_SPACING && relativeMouseY <= COMPONENT_SPACING + 20) {
+            mc.sndManager.playSound("random.click", SoundCategory.GUI_SOUNDS, 1.0F, 1.0F);
+            resetValue();
+        }
+    }
+
+    @Override
+    public void onMouseMove(int x, int y, int width, int relativeMouseX, int relativeMouseY) {
+        buttonDragged(x, y, width, getHeight(), relativeMouseX - (width - BUTTON_WIDTH), relativeMouseY - COMPONENT_SPACING);
+    }
+
+    @Override
+    public void onMouseRelease(int mouseButton, int x, int y, int width, int relativeMouseX, int relativeMouseY) {
+        buttonReleased(mouseButton, x, y, width, getHeight(), relativeMouseX - (width - BUTTON_WIDTH), relativeMouseY - COMPONENT_SPACING);
+    }
+
+    protected abstract void buttonClicked(int mouseButton, int x, int y, int width, int height, int relativeMouseX, int relativeMouseY);
+
+    protected void buttonDragged(int x, int y, int width, int height, int relativeMouseX, int relativeMouseY) { }
+
+    protected void buttonReleased(int mouseButton, int x, int y, int width, int height, int relativeMouseX, int relativeMouseY) { }
+
+    @Override
+    public void onKeyPress(int keyCode, char character) { }
+
+    @Override
+    public boolean matchesSearchTerm(String term)
+    {
+        return I18n.getInstance().translateKey(translationKey).toLowerCase().contains(term.toLowerCase());
+    }
+
+    protected void renderButton(int x, int y, int relativeButtonX, int relativeButtonY, int buttonWidth, int buttonHeight, int relativeMouseX, int relativeMouseY) {
+        if (resetButton.enabled) {
+            resetButton.xPosition = x + relativeButtonX - 20;
+            resetButton.yPosition = y + relativeButtonY;
+
+            resetButton.drawButton(mc, x + relativeMouseX, y + relativeMouseY);
+
+            if (relativeMouseX >= relativeButtonX && relativeMouseX < relativeButtonX + buttonWidth && relativeMouseY >= relativeButtonY && relativeButtonY < relativeButtonY + buttonHeight) {
+                mc.currentScreen.setDesiredCursor(CursorShape.HAND);
+            }
+        }
+    }
+
+    protected void drawRect(int minX, int minY, int maxX, int maxY, int argb)
+    {
+        Tessellator tessellator = Tessellator.instance;
+        GL11.glEnable(GL_BLEND);
+        GL11.glDisable(GL_TEXTURE_2D);
+        GL11.glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+        tessellator.startDrawingQuads();
+        tessellator.setColorRGBA_I(argb & 0x00FFFFFF, argb >> 24 & 0xff);
+        tessellator.addVertex(minX, maxY, 0.0D);
+        tessellator.addVertex(maxX, maxY, 0.0D);
+        tessellator.addVertex(maxX, minY, 0.0D);
+        tessellator.addVertex(minX, minY, 0.0D);
+        tessellator.draw();
+        GL11.glEnable(GL_TEXTURE_2D);
+        GL11.glDisable(GL_BLEND);
+    }
+
+}
diff --git a/game/client/src/main/java/net/minecraft/client/gui/worldsettings/ScreenWorldSettings.java b/game/client/src/main/java/net/minecraft/client/gui/worldsettings/ScreenWorldSettings.java
new file mode 100644
index 000000000..751a62ca9
--- /dev/null
+++ b/game/client/src/main/java/net/minecraft/client/gui/worldsettings/ScreenWorldSettings.java
@@ -0,0 +1,55 @@
+package net.minecraft.client.gui.worldsettings;
+
+import net.minecraft.client.gui.Screen;
+import net.minecraft.client.gui.paged.Page;
+import net.minecraft.client.gui.paged.PageComponent;
+import net.minecraft.client.gui.paged.PageRegistry;
+import net.minecraft.client.gui.paged.ScreenPaged;
+import net.minecraft.core.data.gamerule.GameRule;
+import net.minecraft.core.data.gamerule.GameRuleBoolean;
+import net.minecraft.core.data.registry.Registries;
+import net.minecraft.core.item.Items;
+import net.minecraft.core.world.settings.WorldConfiguration;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.List;
+
+public class ScreenWorldSettings
+    extends ScreenPaged
+{
+    public static final @NotNull PageRegistry CREATE_WORLD_PAGES = new PageRegistry();
+    public static final @NotNull Page PAGE_GAME_RULES = CREATE_WORLD_PAGES.register(new Page("gui.world_settings.page.game_rules.title", Items.PAPER.getDefaultStack()));
+    static {
+        for (final @NotNull GameRule<?> gameRule : Registries.GAME_RULES) {
+            if (gameRule instanceof GameRuleBoolean) {
+                PAGE_GAME_RULES.withComponent(new BooleanGameRuleComponent((GameRuleBoolean) gameRule));
+            }
+        }
+    }
+    public static final @NotNull Page PAGE_WORLD_SETTINGS = CREATE_WORLD_PAGES.register(
+            new Page("gui.world_settings.page.world_settings.title", Items.PAINTBRUSH.getDefaultStack())
+                    .withComponent(new WorldTypeButtonComponent("gui.world_settings.label.world_type", null))
+    );
+
+    private final @NotNull WorldConfiguration worldConfiguration;
+
+    public ScreenWorldSettings(Screen parent, final @NotNull WorldConfiguration worldConfiguration) {
+        super(parent, CREATE_WORLD_PAGES, PAGE_GAME_RULES, "gui.world_settings.label.title", new String[] { "gui.world_settings.button.done" });
+
+        this.worldConfiguration = worldConfiguration;
+
+        final List<PageComponent> gameRulesPageComponents = PAGE_GAME_RULES.getComponents();
+        for (PageComponent component : gameRulesPageComponents) {
+            if (component instanceof BooleanGameRuleComponent) {
+                ((BooleanGameRuleComponent) component).setGameRuleCollection(worldConfiguration.getGameRuleCollection());
+            }
+        }
+
+        final List<PageComponent> worldSettingsPageComponents = PAGE_WORLD_SETTINGS.getComponents();
+        for (PageComponent component : worldSettingsPageComponents) {
+            if (component instanceof WorldTypeButtonComponent) {
+                ((WorldTypeButtonComponent) component).setWorldConfiguration(worldConfiguration);
+            }
+        }
+    }
+}
diff --git a/game/client/src/main/java/net/minecraft/client/gui/worldsettings/WorldTypeButtonComponent.java b/game/client/src/main/java/net/minecraft/client/gui/worldsettings/WorldTypeButtonComponent.java
new file mode 100644
index 000000000..b41282c39
--- /dev/null
+++ b/game/client/src/main/java/net/minecraft/client/gui/worldsettings/WorldTypeButtonComponent.java
@@ -0,0 +1,86 @@
+package net.minecraft.client.gui.worldsettings;
+
+import net.minecraft.client.gui.ButtonElement;
+import net.minecraft.client.gui.SwitchElement;
+import net.minecraft.client.gui.popup.PopupBuilder;
+import net.minecraft.client.gui.popup.PopupScreen;
+import net.minecraft.client.render.window.CursorShape;
+import net.minecraft.core.data.registry.Registries;
+import net.minecraft.core.lang.I18n;
+import net.minecraft.core.net.command.TextFormatting;
+import net.minecraft.core.world.Dimension;
+import net.minecraft.core.world.settings.WorldConfiguration;
+import net.minecraft.core.world.type.WorldTypeGroups;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+public class WorldTypeButtonComponent
+    extends ButtonComponent
+{
+    private @Nullable WorldConfiguration worldConfiguration = null;
+    private final ButtonElement button;
+
+    public WorldTypeButtonComponent(final @NotNull String translationKey, final @Nullable String tooltipTranslationKey) {
+        super(translationKey, tooltipTranslationKey);
+
+        this.button = new ButtonElement(0, 0, 0, 150, 20, "");
+    }
+
+    public void setWorldConfiguration(final @NotNull WorldConfiguration worldConfiguration) {
+        this.worldConfiguration = worldConfiguration;
+        this.button.displayString = I18n.getInstance().translateKey(this.worldConfiguration.getWorldTypeGroup().get(Dimension.OVERWORLD).getLanguageKey() + ".name");
+    }
+
+    @Override
+    public void resetValue() {
+        this.worldConfiguration.setWorldTypeGroup(WorldTypeGroups.DEFAULT);
+        this.button.displayString = I18n.getInstance().translateKey(this.worldConfiguration.getWorldTypeGroup().get(Dimension.OVERWORLD).getLanguageKey() + ".name");
+    }
+
+    @Override
+    public boolean isDefault() {
+        return this.worldConfiguration.getWorldTypeGroup() == WorldTypeGroups.DEFAULT;
+    }
+
+    @Override
+    protected void buttonClicked(int mouseButton, int x, int y, int width, int height, int relativeMouseX, int relativeMouseY) {
+        I18n i18n = I18n.getInstance();
+        String[] keys = new String[WorldTypeGroups.GROUPS.size()];
+        String[] descs = new String[WorldTypeGroups.GROUPS.size()];
+        for (int i = 0; i < keys.length; i++) {
+            keys[i] = i18n.translateKey(WorldTypeGroups.GROUPS.get(i).get(Dimension.OVERWORLD).getLanguageKey() + ".name");
+            descs[i] = i18n.translateKey(WorldTypeGroups.GROUPS.get(i).get(Dimension.OVERWORLD).getLanguageKey() + ".desc") + "\n" +
+                    TextFormatting.GRAY + Registries.WORLD_TYPES.getKey(WorldTypeGroups.GROUPS.get(i).get(Dimension.OVERWORLD));
+        }
+
+        PopupScreen popup = new PopupBuilder(mc.currentScreen, 150)
+                .closeOnEsc(0)
+                .closeOnClickOut(0)
+                .withLabel("gui.world_settings.label.select_world_type")
+                .withList("worldTypeList", 140, keys, descs, WorldTypeGroups.GROUPS.indexOf(this.worldConfiguration.getWorldTypeGroup()), true)
+                .withOnCloseListener((statusCode, results) -> {
+                    if (statusCode == 1) {
+                        this.worldConfiguration.setWorldTypeGroup(WorldTypeGroups.GROUPS.get((Integer) results.get("worldTypeList")));
+                        this.button.displayString = I18n.getInstance().translateKey(this.worldConfiguration.getWorldTypeGroup().get(Dimension.OVERWORLD).getLanguageKey() + ".name");
+                    }
+                })
+                .build();
+        mc.displayScreen(popup);
+    }
+
+    @Override
+    protected void renderButton(int x, int y, int relativeButtonX, int relativeButtonY, int buttonWidth, int buttonHeight, int relativeMouseX, int relativeMouseY) {
+        super.renderButton(x, y, relativeButtonX, relativeButtonY, buttonWidth, buttonHeight, relativeMouseX, relativeMouseY);
+
+        this.button.xPosition = x + relativeButtonX;
+        this.button.yPosition = y + relativeButtonY;
+        this.button.width = buttonWidth;
+        this.button.height = buttonHeight;
+
+        this.button.drawButton(mc, x + relativeMouseX, y + relativeMouseY);
+
+        if (relativeMouseX >= relativeButtonX && relativeMouseX < relativeButtonX + buttonWidth && relativeMouseY >= relativeButtonY && relativeButtonY < relativeButtonY + buttonHeight) {
+            mc.currentScreen.setDesiredCursor(CursorShape.HAND);
+        }
+    }
+}
diff --git a/game/core/src/main/java/net/minecraft/core/data/gamerule/GameRule.java b/game/core/src/main/java/net/minecraft/core/data/gamerule/GameRule.java
index bcae8c7bd..d43112870 100644
--- a/game/core/src/main/java/net/minecraft/core/data/gamerule/GameRule.java
+++ b/game/core/src/main/java/net/minecraft/core/data/gamerule/GameRule.java
@@ -6,11 +6,13 @@ import org.jetbrains.annotations.NotNull;
 public abstract class GameRule<T>
 {
     private final @NotNull String key;
+    private final @NotNull String translationKey;
     private final T defaultValue;
 
-    public GameRule(@NotNull final String key, final T defaultValue)
+    public GameRule(final @NotNull String key, final @NotNull String translationKey, final T defaultValue)
     {
         this.key = key;
+        this.translationKey = translationKey;
         this.defaultValue = defaultValue;
     }
 
@@ -19,6 +21,10 @@ public abstract class GameRule<T>
         return this.key;
     }
 
+    public @NotNull String getTranslationKey() {
+        return this.translationKey;
+    }
+
     public T getDefaultValue()
     {
         return this.defaultValue;
diff --git a/game/core/src/main/java/net/minecraft/core/data/gamerule/GameRuleBoolean.java b/game/core/src/main/java/net/minecraft/core/data/gamerule/GameRuleBoolean.java
index 1d26b64ce..4a4b04d10 100644
--- a/game/core/src/main/java/net/minecraft/core/data/gamerule/GameRuleBoolean.java
+++ b/game/core/src/main/java/net/minecraft/core/data/gamerule/GameRuleBoolean.java
@@ -9,8 +9,8 @@ import org.jetbrains.annotations.Nullable;
 public class GameRuleBoolean
     extends GameRule<Boolean>
 {
-    public GameRuleBoolean(String key, Boolean defaultValue) {
-        super(key, defaultValue);
+    public GameRuleBoolean(String key, String translationKey, Boolean defaultValue) {
+        super(key, translationKey, defaultValue);
     }
 
     @Override
diff --git a/game/core/src/main/java/net/minecraft/core/data/gamerule/GameRuleInteger.java b/game/core/src/main/java/net/minecraft/core/data/gamerule/GameRuleInteger.java
index 23ef1ac6a..80a9bfe31 100644
--- a/game/core/src/main/java/net/minecraft/core/data/gamerule/GameRuleInteger.java
+++ b/game/core/src/main/java/net/minecraft/core/data/gamerule/GameRuleInteger.java
@@ -6,8 +6,8 @@ import com.mojang.nbt.tags.Tag;
 import org.jetbrains.annotations.NotNull;
 
 public class GameRuleInteger extends GameRule<Integer> {
-    public GameRuleInteger(final String key, final Integer defaultValue) {
-        super(key, defaultValue);
+    public GameRuleInteger(final String key, final String translationKey, final Integer defaultValue) {
+        super(key, translationKey, defaultValue);
     }
 
     @Override
diff --git a/game/core/src/main/java/net/minecraft/core/data/gamerule/GameRules.java b/game/core/src/main/java/net/minecraft/core/data/gamerule/GameRules.java
index 6a79d2d0a..2452bcfaf 100644
--- a/game/core/src/main/java/net/minecraft/core/data/gamerule/GameRules.java
+++ b/game/core/src/main/java/net/minecraft/core/data/gamerule/GameRules.java
@@ -4,19 +4,19 @@ import net.minecraft.core.data.registry.Registries;
 
 public abstract class GameRules
 {
-    public static GameRuleBoolean KEEP_INVENTORY = register(new GameRuleBoolean("keepInventory", false));
-    public static GameRuleBoolean ALLOW_SPRINTING = register(new GameRuleBoolean("allowSprinting", false));
-    public static GameRuleBoolean ALLOW_SLEEPING = register(new GameRuleBoolean("allowSleeping", true));
-    public static GameRuleBoolean DO_NIGHTMARES = register(new GameRuleBoolean("doNightmares", true));
-    public static GameRuleBoolean DO_SEASONAL_GROWTH = register(new GameRuleBoolean("doSeasonalGrowth", true));
-    public static GameRuleBoolean TREECAPITATOR = register(new GameRuleBoolean("treecapitator", false));
-    public static GameRuleBoolean DWARF_MODE = register(new GameRuleBoolean("dwarfMode", false));
-    public static GameRuleBoolean MOB_GRIEFING = register(new GameRuleBoolean("mobGriefing", true));
-    public static GameRuleBoolean DO_DAY_CYCLE = register(new GameRuleBoolean("doDaylightCycle", true));
-    public static GameRuleBoolean DO_WEATHER_CYCLE = register(new GameRuleBoolean("doWeatherCycle", true));
-    public static GameRuleBoolean DO_FIRE_SPREAD = register(new GameRuleBoolean("doFireSpread", true));
-    public static GameRuleBoolean INSTANT_HEALING = register(new GameRuleBoolean("instantHealing", false));
-    public static GameRuleInteger RANDOM_TICK_SPEED = register(new GameRuleInteger("randomTickSpeed", 4));
+    public static GameRuleBoolean KEEP_INVENTORY = register(new GameRuleBoolean("keepInventory", "gamerule.keep_inventory", false));
+    public static GameRuleBoolean ALLOW_SPRINTING = register(new GameRuleBoolean("allowSprinting", "gamerule.allow_sprinting", false));
+    public static GameRuleBoolean ALLOW_SLEEPING = register(new GameRuleBoolean("allowSleeping", "gamerule.allow_sleeping", true));
+    public static GameRuleBoolean DO_NIGHTMARES = register(new GameRuleBoolean("doNightmares", "gamerule.do_nightmares", true));
+    public static GameRuleBoolean DO_SEASONAL_GROWTH = register(new GameRuleBoolean("doSeasonalGrowth", "gamerule.do_seasonal_growth", true));
+    public static GameRuleBoolean TREECAPITATOR = register(new GameRuleBoolean("treecapitator", "gamerule.treecapitator", false));
+    public static GameRuleBoolean DWARF_MODE = register(new GameRuleBoolean("dwarfMode", "gamerule.dwarf_mode", false));
+    public static GameRuleBoolean MOB_GRIEFING = register(new GameRuleBoolean("mobGriefing", "gamerule.mob_griefing", true));
+    public static GameRuleBoolean DO_DAY_CYCLE = register(new GameRuleBoolean("doDaylightCycle", "gamerule.do_day_night_cycle", true));
+    public static GameRuleBoolean DO_WEATHER_CYCLE = register(new GameRuleBoolean("doWeatherCycle", "gamerule.do_weather_cycle", true));
+    public static GameRuleBoolean DO_FIRE_SPREAD = register(new GameRuleBoolean("doFireSpread", "gamerule.do_fire_spread", true));
+    public static GameRuleBoolean INSTANT_HEALING = register(new GameRuleBoolean("instantHealing", "gamerule.instant_healing", false));
+    public static GameRuleInteger RANDOM_TICK_SPEED = register(new GameRuleInteger("randomTickSpeed", "gamerule.random_tick_speed", 4));
 
     public static <T extends GameRule<?>> T register(T gameRule)
     {
diff --git a/game/core/src/main/java/net/minecraft/core/world/settings/WorldConfiguration.java b/game/core/src/main/java/net/minecraft/core/world/settings/WorldConfiguration.java
index cd6b5ea3d..2b4340dc8 100644
--- a/game/core/src/main/java/net/minecraft/core/world/settings/WorldConfiguration.java
+++ b/game/core/src/main/java/net/minecraft/core/world/settings/WorldConfiguration.java
@@ -1,5 +1,6 @@
 package net.minecraft.core.world.settings;
 
+import net.minecraft.core.data.gamerule.GameRuleCollection;
 import net.minecraft.core.lang.I18n;
 import net.minecraft.core.player.gamemode.Gamemode;
 import net.minecraft.core.util.helper.ChatAllowedCharacters;
@@ -18,6 +19,7 @@ public class WorldConfiguration {
     private boolean cheatsEnabled = false;
     private @NotNull Gamemode gamemode = Gamemode.survival;
     private @NotNull WorldTypeGroups.Group worldTypeGroup = WorldTypeGroups.DEFAULT;
+    private final @NotNull GameRuleCollection gameRuleCollection = new GameRuleCollection();
 
     public WorldConfiguration() {
     }
@@ -95,6 +97,10 @@ public class WorldConfiguration {
         this.worldTypeGroup = worldTypeGroup;
     }
 
+    public @NotNull GameRuleCollection getGameRuleCollection() {
+        return this.gameRuleCollection;
+    }
+
     public @NotNull String getFolderName(final @NotNull ISaveFormat saveFormat) {
         final char @NotNull [] ac = ChatAllowedCharacters.ALLOWED_CHARACTERS_ARRAY;
         @NotNull String folderName = this.worldName.trim();
@@ -106,9 +112,11 @@ public class WorldConfiguration {
             folderName = folderName.replace(c, '_');
         }
 
+        final @NotNull String fixedFolderName = folderName;
+
         int count = 1;
         for (; saveFormat.getLevelData(folderName) != null; count++) {
-            folderName = folderName + " (" + count + ")";
+            folderName = fixedFolderName + " (" + count + ")";
         }
         return folderName;
     }
diff --git a/game/core/src/main/resources/lang/en_US/gamerules.lang b/game/core/src/main/resources/lang/en_US/gamerules.lang
new file mode 100644
index 000000000..c3ba780c4
--- /dev/null
+++ b/game/core/src/main/resources/lang/en_US/gamerules.lang
@@ -0,0 +1,26 @@
+gamerule.keep_inventory.name=Keep Inventory
+gamerule.keep_inventory.desc=If enabled, players retain their items on death.
+gamerule.allow_sprinting.name=Allow Sprinting
+gamerule.allow_sprinting.desc=If enabled, players can sprint in a manner similar to Minecraft Beta 1.8 and later versions.
+gamerule.allow_sleeping.name=Allow Sleeping
+gamerule.allow_sleeping.desc=If disabled, players cannot sleep to skip the night. However, right-clicking on a bed will still set their spawn point.
+gamerule.do_nightmares.name=Nightmares
+gamerule.do_nightmares.desc=If enabled, there is a chance players will be attacked by a mob if they sleep in an unsafe location.
+gamerule.do_seasonal_growth.name=Seasonal Growth
+gamerule.do_seasonal_growth.desc=If disabled, tall grass and flowers will not randomly pop up in spring.
+gamerule.treecapitator.name=Treecapitator
+gamerule.treecapitator.desc=If enabled, trees will be instantly mined in their entirety when their bottom log is broken with an axe.
+gamerule.dwarf_mode.name=Dwarf Mode
+gamerule.dwarf_mode.desc=If enabled, all players will become one-block-tall dwarves.
+gamerule.mob_griefing.name=Mob Griefing
+gamerule.mob_griefing.desc=If disabled, explosions created by mobs will not destroy blocks.
+gamerule.do_day_night_cycle.name=Day/Night Cycle
+gamerule.do_day_night_cycle.desc=If disabled, the day/night cycle is paused.
+gamerule.do_weather_cycle.name=Weather
+gamerule.do_weather_cycle.desc=If disabled, the weather will not randomly change.
+gamerule.do_fire_spread.name=Fire Spread
+gamerule.do_fire_spread.desc=If disabled, fire will not spread.
+gamerule.instant_healing.name=Instant Healing from Food
+gamerule.instant_healing.desc=If enabled, food will heal the player instantly as it did in older versions of BTA!.
+gamerule.random_tick_speed.name=Random Tick Rate
+gamerule.random_tick_speed.desc=Determines how many blocks are randomly ticked per game tick.
diff --git a/game/core/src/main/resources/lang/en_US/gui.lang b/game/core/src/main/resources/lang/en_US/gui.lang
index 5991b3a2c..c11da97f7 100644
--- a/game/core/src/main/resources/lang/en_US/gui.lang
+++ b/game/core/src/main/resources/lang/en_US/gui.lang
@@ -93,19 +93,17 @@ gui.create_world.button.gamemode=Mode: %s
 gui.create_world.button.cheats=Cheats: %s
 gui.create_world.button.cheats.on=ON
 gui.create_world.button.cheats.off=OFF
-gui.create_world.button.world_type=World Type: %s
+gui.create_world.button.world_settings=World Settings
 gui.create_world.label.new_world=New World
-gui.create_world.label.select_world_type=Select World Type
 
-gui.create_world.label.title=Create New World
-gui.create_world.button.cancel=Cancel
-gui.create_world.button.create_world=Create World
-
-gui.create_world.pages.general.title=General
-gui.create_world.pages.general.label.world_name=World Name
-gui.create_world.pages.general.label.world_seed=World Seed
-gui.create_world.pages.world_settings.title=World Settings
-gui.create_world.pages.game_rules.title=Game Rules
+gui.world_settings.label.title=World Settings
+gui.world_settings.button.done=Done
+gui.world_settings.page.game_rules.title=Game Rules
+gui.world_settings.page.world_settings.title=World Settings
+gui.world_settings.page.game_rules.button.on=ON
+gui.world_settings.page.game_rules.button.off=OFF
+gui.world_settings.label.select_world_type=Select World Type
+gui.world_settings.label.world_type=World Type
 
 gui.dispenser.label.dispenser=Dispenser
 gui.dispenser.label.inventory=Inventory
@@ -273,6 +271,12 @@ gui.options.page.debug.button.garbage_collect=Run Garbage Collector
 
 gui.options.page.search.title=Search
 
+gui.options.difficultylock.button.no=No
+gui.options.difficultylock.button.yes=Yes
+gui.options.difficultylock.warning.1=Are you sure you wish
+gui.options.difficultylock.warning.2=to lock this world's difficulty?
+gui.options.difficultylock.warning.3=(This cannot be undone)
+
 gui.sound_test.label.title=Sound Test
 gui.sound_test.label.repo=Sound Repository: %s
 gui.sound_test.label.id=ID: %s
