From 0fbc8903f309b50baa92dbfaff0d6445e0274bb0 Mon Sep 17 00:00:00 2001 From: Loki Date: Mon, 9 Mar 2026 18:26:00 -0500 Subject: [PATCH 01/10] Update README, remove servers.txt references --- README.md | 23 ++--------------------- 1 file changed, 2 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index 8ea3141ab..e4272e379 100644 --- a/README.md +++ b/README.md @@ -35,30 +35,11 @@ Basic LAN multiplayer is available on the Windows build - Other players on the same LAN can discover the session from the in-game Join Game menu - Game connections use TCP port `25565` by default - LAN discovery uses UDP port `25566` -- Add servers to your server list with `servers.txt` (temp solution) +- Add servers to your server list with the in-game Add Server button (temp) - Rename yourself without losing data by keeping your `uid.dat` Parts of this feature are based on code from [LCEMP](https://github.com/LCEMP/LCEMP) (thanks!) -### servers.txt - -To add a server to your game, create the `servers.txt` file in the same directory as you have `Minecraft.Client.exe`. Inside, follow this format: -``` -serverip.example.com -25565 -The name of your server in UI! -``` - -For example, here's a valid servers.txt -``` -1.1.1.1 -25565 -Cloudflare's Very Own LCE Server -127.0.0.1 -25565 -Localhost Test Crap -``` - ### Launch Arguments | Argument | Description | @@ -100,7 +81,7 @@ Minecraft.Client.exe -name Steve -fullscreen 2. Clone the repository. 3. Open the project by double-clicking `MinecraftConsoles.sln`. 4. Make sure `Minecraft.Client` is set as the Startup Project. -5. Set the build configuration to **Debug** (Release is also OK but has some bugs) and the target platform to **Windows64**, then build and run. +5. Set the build configuration to **Debug** (Release is also ok but missing some debug features) and the target platform to **Windows64**, then build and run. ### CMake (Windows x64) From e6eafda90e7827909acb75a23bc50b4b9dbf4a6f Mon Sep 17 00:00:00 2001 From: Loki Date: Mon, 9 Mar 2026 18:27:02 -0500 Subject: [PATCH 02/10] Remove another servers.txt reference --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e4272e379..0c476666e 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ This project contains the source code of Minecraft Legacy Console Edition v1.6.0560.0 (TU19) with some fixes and improvements applied. ## Download -Windows users can download our [Nightly Build](https://github.com/smartcmd/MinecraftConsoles/releases/tag/nightly)! Simply download the `.zip` file and extract it to a folder where you'd like to keep the game. You can set your username in `username.txt` (you'll have to make this file) and add servers to connect to in `servers.txt` +Windows users can download our [Nightly Build](https://github.com/smartcmd/MinecraftConsoles/releases/tag/nightly)! Simply download the `.zip` file and extract it to a folder where you'd like to keep the game. You can set your username in `username.txt` (you'll have to make this file) ## Platform Support From 58c236ead5c35248a9c993c7b296e41c2799d305 Mon Sep 17 00:00:00 2001 From: Loki Rautio Date: Mon, 9 Mar 2026 20:49:50 -0500 Subject: [PATCH 03/10] Disable git LFS It was never even enabled properly to begin with --- .gitattributes | 8 -------- 1 file changed, 8 deletions(-) diff --git a/.gitattributes b/.gitattributes index 2a377d08a..e69de29bb 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,8 +0,0 @@ -*.png filter=lfs diff=lfs merge=lfs -text -*.jpg filter=lfs diff=lfs merge=lfs -text -*.ogg filter=lfs diff=lfs merge=lfs -text -*.binka filter=lfs diff=lfs merge=lfs -text -*.arc filter=lfs diff=lfs merge=lfs -text -*.ttf filter=lfs diff=lfs merge=lfs -text -*.bin filter=lfs diff=lfs merge=lfs -text -*.ico filter=lfs diff=lfs merge=lfs -text From 3bcf588fbe041bd9d81f51348c3e98876dc9d4e2 Mon Sep 17 00:00:00 2001 From: Marlian <84173858+MCbabel@users.noreply.github.com> Date: Tue, 10 Mar 2026 04:02:39 +0100 Subject: [PATCH 04/10] Fix crash when loading saved tutorial worlds (#1001) writeRuleFile() was missing the schematic file count integer before the schematic entries. The reader in readRuleFile() expected this count, causing a stream misalignment that led to an assertion failure (Unrecognised schematic version) when reloading a saved tutorial world. The fix writes the count on save and adds backward-compatible reading that detects old saves (without count) via a peek heuristic and falls back to count-less parsing. Co-authored-by: MCbabel --- .../Common/GameRules/GameRuleManager.cpp | 36 ++++++++++++++----- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/Minecraft.Client/Common/GameRules/GameRuleManager.cpp b/Minecraft.Client/Common/GameRules/GameRuleManager.cpp index ff294a650..95434c08c 100644 --- a/Minecraft.Client/Common/GameRules/GameRuleManager.cpp +++ b/Minecraft.Client/Common/GameRules/GameRuleManager.cpp @@ -344,6 +344,7 @@ void GameRuleManager::writeRuleFile(DataOutputStream *dos) // Write schematic files. unordered_map *files; files = getLevelGenerationOptions()->getUnfinishedSchematicFiles(); + dos->writeInt((int)files->size()); for ( auto& it : *files ) { const wstring& filename = it.first; @@ -497,17 +498,36 @@ bool GameRuleManager::readRuleFile(LevelGenerationOptions *lgo, byte *dIn, UINT }*/ // subfile + // Old saves didn't write a numFiles count before the schematic entries. + // Detect this: a real count is small, but a UTF filename prefix reads as a large int. UINT numFiles = contentDis->readInt(); - for (UINT i = 0; i < numFiles; i++) + + if (lgo->isFromSave() && numFiles > 100) { - wstring sFilename = contentDis->readUTF(); - int length = contentDis->readInt(); - byteArray ba( length ); - - contentDis->read(ba); - - levelGenerator->loadSchematicFile(sFilename, ba.data, ba.length); + contentDis->skip(-4); + while (true) + { + int peek = contentDis->readInt(); + if (peek <= 100) { contentDis->skip(-4); break; } + contentDis->skip(-4); + wstring sFilename = contentDis->readUTF(); + int length = contentDis->readInt(); + byteArray ba( length ); + contentDis->read(ba); + levelGenerator->loadSchematicFile(sFilename, ba.data, ba.length); + } + } + else + { + for (UINT i = 0; i < numFiles; i++) + { + wstring sFilename = contentDis->readUTF(); + int length = contentDis->readInt(); + byteArray ba( length ); + contentDis->read(ba); + levelGenerator->loadSchematicFile(sFilename, ba.data, ba.length); + } } LEVEL_GEN_ID lgoID = LEVEL_GEN_ID_NULL; From 5f777a7f45455641b9ff4bb534cadcf0f763b0a3 Mon Sep 17 00:00:00 2001 From: Alezito2008 <92759854+Alezito2008@users.noreply.github.com> Date: Tue, 10 Mar 2026 00:03:39 -0300 Subject: [PATCH 05/10] Fix: Prevent clicking disabled checkboxes (#1075) --- Minecraft.Client/Common/UI/UIScene.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Minecraft.Client/Common/UI/UIScene.cpp b/Minecraft.Client/Common/UI/UIScene.cpp index 5630e9726..0088f43d4 100644 --- a/Minecraft.Client/Common/UI/UIScene.cpp +++ b/Minecraft.Client/Common/UI/UIScene.cpp @@ -578,9 +578,12 @@ bool UIScene::handleMouseClick(F32 x, F32 y) if (bestCtrl->getControlType() == UIControl::eCheckBox) { UIControl_CheckBox *cb = static_cast(bestCtrl); - bool newState = !cb->IsChecked(); - cb->setChecked(newState); - handleCheckboxToggled((F64)bestId, newState); + if (cb->IsEnabled()) + { + bool newState = !cb->IsChecked(); + cb->setChecked(newState); + handleCheckboxToggled((F64)bestId, newState); + } } else { From c90a6bf5ab4d1d96ac510f7357c9618c2bf4bc77 Mon Sep 17 00:00:00 2001 From: "Us3ful\"-Dev" Date: Tue, 10 Mar 2026 04:05:56 +0100 Subject: [PATCH 06/10] Fixed Enderman, monster aggro in creative (#1051) Fixed endermans by making a invulnerable check --- Minecraft.World/EnderMan.cpp | 7 ++++++- Minecraft.World/Monster.cpp | 9 ++++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/Minecraft.World/EnderMan.cpp b/Minecraft.World/EnderMan.cpp index e12318187..da469a3a2 100644 --- a/Minecraft.World/EnderMan.cpp +++ b/Minecraft.World/EnderMan.cpp @@ -410,9 +410,14 @@ bool EnderMan::hurt(DamageSource *source, float damage) if ( dynamic_cast(source) != nullptr && source->getEntity()->instanceof(eTYPE_PLAYER)) { - aggroedByPlayer = true; + if (!dynamic_pointer_cast(source->getEntity())->abilities.invulnerable) + { + aggroedByPlayer = true; + } + else setCreepy(false); } + if (dynamic_cast(source) != nullptr) { aggroedByPlayer = false; diff --git a/Minecraft.World/Monster.cpp b/Minecraft.World/Monster.cpp index 2de453153..ad19a36d4 100644 --- a/Minecraft.World/Monster.cpp +++ b/Minecraft.World/Monster.cpp @@ -60,7 +60,14 @@ bool Monster::hurt(DamageSource *source, float dmg) if (sourceEntity != shared_from_this()) { - attackTarget = sourceEntity; + if (sourceEntity->instanceof(eTYPE_PLAYER)) + { + if (!dynamic_pointer_cast(sourceEntity)->abilities.invulnerable) + { + attackTarget = sourceEntity; + } + } + else attackTarget = sourceEntity; } return true; } From 91ae76f132678b010dabd30dbd87abf2087dd929 Mon Sep 17 00:00:00 2001 From: Marlian <84173858+MCbabel@users.noreply.github.com> Date: Tue, 10 Mar 2026 04:06:38 +0100 Subject: [PATCH 07/10] Fix tamed horses despawning when player moves away (#1057) Co-authored-by: MCbabel --- Minecraft.World/EntityHorse.cpp | 9 +++++++++ Minecraft.World/EntityHorse.h | 1 + 2 files changed, 10 insertions(+) diff --git a/Minecraft.World/EntityHorse.cpp b/Minecraft.World/EntityHorse.cpp index 32c9eb2de..0bf5bc080 100644 --- a/Minecraft.World/EntityHorse.cpp +++ b/Minecraft.World/EntityHorse.cpp @@ -515,6 +515,15 @@ bool EntityHorse::canSpawn() return Animal::canSpawn(); } +bool EntityHorse::removeWhenFarAway() +{ + if (isTamed()) return false; + if (isSaddled()) return false; + if (isLeashed()) return false; + if (getArmorType() > 0) return false; + return Animal::removeWhenFarAway(); +} + shared_ptr EntityHorse::getClosestMommy(shared_ptr baby, double searchRadius) { diff --git a/Minecraft.World/EntityHorse.h b/Minecraft.World/EntityHorse.h index c2784491a..c91da172a 100644 --- a/Minecraft.World/EntityHorse.h +++ b/Minecraft.World/EntityHorse.h @@ -192,6 +192,7 @@ private: public: virtual void containerChanged(); virtual bool canSpawn(); + virtual bool removeWhenFarAway() override; protected: virtual shared_ptr getClosestMommy(shared_ptr baby, double searchRadius); From c998346312c753fa4359804c2c1823e23bce5b91 Mon Sep 17 00:00:00 2001 From: eh-K <165239265+eh-K@users.noreply.github.com> Date: Mon, 9 Mar 2026 22:07:38 -0500 Subject: [PATCH 08/10] FIX: Bonus Chests spawn again when loading back in. #982 (#992) * Fixed bug where Bonus Chests would spawn again when loading back into it. Fixes #982 Added a check for if the world is new. Meaning no more additional chests if the world is loaded up again. * Replace NULL with nullptr for chest check --- Minecraft.World/BonusChestFeature.cpp | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/Minecraft.World/BonusChestFeature.cpp b/Minecraft.World/BonusChestFeature.cpp index cd33e60ae..86dc97258 100644 --- a/Minecraft.World/BonusChestFeature.cpp +++ b/Minecraft.World/BonusChestFeature.cpp @@ -24,18 +24,21 @@ bool BonusChestFeature::place(Level *level, Random *random, int x, int y, int z) bool BonusChestFeature::place(Level *level, Random *random, int x, int y, int z, bool force) { - if( !force ) + //Will only spawn a bonus chest if the world is new and has never been saved. + if (level->isNew) { - int t = 0; - while (((t = level->getTile(x, y, z)) == 0 || t == Tile::leaves_Id) && y > 1) + if( !force ) + { + int t = 0; + while (((t = level->getTile(x, y, z)) == 0 || t == Tile::leaves_Id) && y > 1) y--; - if (y < 1) - { - return false; + if (y < 1) + { + return false; + } + y++; } - y++; - } for (int i = 0; i < 4; i++) { @@ -85,4 +88,6 @@ bool BonusChestFeature::place(Level *level, Random *random, int x, int y, int z, } return false; + + } } From d7596aa28c0ff7773e5a64155e54f2821517c591 Mon Sep 17 00:00:00 2001 From: la <76826837+3UR@users.noreply.github.com> Date: Tue, 10 Mar 2026 13:30:01 +1000 Subject: [PATCH 09/10] Fix issue where visually the HUD shows you have 0 hearts when you dont (#1089) * Fix for issue where player is able to stay alive with zero hearts in their healthbar. * use static cast over c style cast --- Minecraft.Client/Common/UI/IUIScene_HUD.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Minecraft.Client/Common/UI/IUIScene_HUD.cpp b/Minecraft.Client/Common/UI/IUIScene_HUD.cpp index fd9779665..d2754789c 100644 --- a/Minecraft.Client/Common/UI/IUIScene_HUD.cpp +++ b/Minecraft.Client/Common/UI/IUIScene_HUD.cpp @@ -195,8 +195,8 @@ void IUIScene_HUD::renderPlayerHealth() // Update health bool blink = pMinecraft->localplayers[iPad]->invulnerableTime / 3 % 2 == 1; if (pMinecraft->localplayers[iPad]->invulnerableTime < 10) blink = false; - int currentHealth = pMinecraft->localplayers[iPad]->getHealth(); - int oldHealth = pMinecraft->localplayers[iPad]->lastHealth; + int currentHealth = static_cast(ceil(pMinecraft->localplayers[iPad]->getHealth())); + int oldHealth = static_cast(ceil(pMinecraft->localplayers[iPad]->lastHealth)); bool bHasPoison = pMinecraft->localplayers[iPad]->hasEffect(MobEffect::poison); bool bHasWither = pMinecraft->localplayers[iPad]->hasEffect(MobEffect::wither); AttributeInstance *maxHealthAttribute = pMinecraft->localplayers[iPad]->getAttribute(SharedMonsterAttributes::MAX_HEALTH); From a195ac7172642196a244260291f966ed7cea1edc Mon Sep 17 00:00:00 2001 From: Loki Date: Tue, 10 Mar 2026 09:37:52 -0500 Subject: [PATCH 10/10] Only single topic PRs, please - CONTRIBUTING.md --- CONTRIBUTING.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c75279d7d..855491da1 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -46,6 +46,13 @@ However, we would accept changes that... - Having workable multi-platform compilation for ARM, Consoles, Linux - Being a good base for further expansion and modding of LCE, such as backports and "modpacks". +# Scope of PRs +All Pull Requests should fully document the changes they include in their file changes. They should also be limited to one general topic and not touch all over the codebase unless its justifiable. + +For example, we would not accept a PR that reworks UI, multiplayer code, and furnace ticking even if its a "fixup" PR as its too difficult to review a ton of code changes that are all irrelevant from each other. However, a PR focused on adding a bunch of commands or fixes several crashes that are otherwise irrelevant to each other would be accepted. + +If your PR includes any undocumented changes it will be closed. + # Use of AI and LLMs We currently do not accept any new code into the project that was written largely, entirely, or even noticably by an LLM. All contributions should be made by humans that understand the codebase.