From fe65ec24f199c79352f0bab971e1ad8b5c611fd9 Mon Sep 17 00:00:00 2001 From: Tuff CWC Date: Mon, 9 Mar 2026 21:02:26 +0100 Subject: [PATCH 01/11] Remove dead link from README (#1064) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 122157ba8..8ea3141ab 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ ## Introduction -This project contains the source code of Minecraft Legacy Console Edition v1.6.0560.0 (TU19) from https://archive.org/details/minecraft-legacy-console-edition-source-code, with some fixes and improvements applied. +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` From e9dba1fa5658b80833ab5b39b0e1028c33794c95 Mon Sep 17 00:00:00 2001 From: la <76826837+3UR@users.noreply.github.com> Date: Tue, 10 Mar 2026 07:01:17 +1000 Subject: [PATCH 02/11] Prevent TNT Minecart exploding with TNT disabled (#1067) This set of changes was made to make the code better mimic TU20 based on its disassembly --- Minecraft.World/MinecartTNT.cpp | 39 ++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/Minecraft.World/MinecartTNT.cpp b/Minecraft.World/MinecartTNT.cpp index 6e72d66b7..18681aa46 100644 --- a/Minecraft.World/MinecartTNT.cpp +++ b/Minecraft.World/MinecartTNT.cpp @@ -64,28 +64,34 @@ void MinecartTNT::destroy(DamageSource *source) double speedSqr = xd * xd + zd * zd; - if (!source->isExplosion()) + if (!app.GetGameHostOption(eGameHostOption_TNT) || !source->isExplosion()) { - spawnAtLocation(std::make_shared(Tile::tnt, 1), 0); + spawnAtLocation( shared_ptr( new ItemInstance(Tile::tnt, 1) ), 0); } - if (source->isFire() || source->isExplosion() || speedSqr >= 0.01f) + if (app.GetGameHostOption(eGameHostOption_TNT)) { - explode(speedSqr); + if (source->isFire() || source->isExplosion() || speedSqr >= 0.01f) + { + explode(speedSqr); + } } } void MinecartTNT::explode(double speedSqr) { + if (!app.GetGameHostOption(eGameHostOption_TNT)) + { + remove(); + return; + } + if (!level->isClientSide) { double speed = sqrt(speedSqr); - if (speed > 5.0) speed = 5.0; - if (app.GetGameHostOption(eGameHostOption_TNT)) - { - level->explode(shared_from_this(), x, y, z, static_cast(4 + random->nextDouble() * 1.5f * speed), true); - remove(); - } + if (speed > 5) speed = 5; + level->explode(shared_from_this(), x, y, z, (float) (4 + random->nextDouble() * 1.5f * speed), true); + remove(); } } @@ -122,12 +128,15 @@ void MinecartTNT::handleEntityEvent(byte eventId) void MinecartTNT::primeFuse() { - fuse = 80; - - if (!level->isClientSide) + if (app.GetGameHostOption(eGameHostOption_TNT)) { - level->broadcastEntityEvent(shared_from_this(), EVENT_PRIME); - level->playEntitySound(shared_from_this(), eSoundType_RANDOM_FUSE, 1, 1.0f); + fuse = 80; + + if (!level->isClientSide) + { + level->broadcastEntityEvent(shared_from_this(), EVENT_PRIME); + level->playEntitySound(shared_from_this(), eSoundType_RANDOM_FUSE, 1, 1.0f); + } } } From 0fbc8903f309b50baa92dbfaff0d6445e0274bb0 Mon Sep 17 00:00:00 2001 From: Loki Date: Mon, 9 Mar 2026 18:26:00 -0500 Subject: [PATCH 03/11] 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 04/11] 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 05/11] 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 06/11] 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 07/11] 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 08/11] 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 09/11] 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 10/11] 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 11/11] 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);