From 1f94cfce4bf1f269a05497911eff4bccaea391df Mon Sep 17 00:00:00 2001 From: Smorki Date: Sun, 26 Jul 2026 13:33:08 +0300 Subject: [PATCH 1/3] Optimize Villager food inventory checks --- .../entity/npc/villager/Villager.java.patch | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 gale-server/minecraft-patches/sources/net/minecraft/world/entity/npc/villager/Villager.java.patch diff --git a/gale-server/minecraft-patches/sources/net/minecraft/world/entity/npc/villager/Villager.java.patch b/gale-server/minecraft-patches/sources/net/minecraft/world/entity/npc/villager/Villager.java.patch new file mode 100644 index 00000000..ac1f3b6c --- /dev/null +++ b/gale-server/minecraft-patches/sources/net/minecraft/world/entity/npc/villager/Villager.java.patch @@ -0,0 +1,42 @@ +--- a/net/minecraft/world/entity/npc/villager/Villager.java ++++ b/net/minecraft/world/entity/npc/villager/Villager.java +@@ -697,8 +_,12 @@ + + private void eatUntilFull() { + if (this.hungry() && this.countFoodPointsInInventory() != 0) { +- for (int slot = 0; slot < this.getInventory().getContainerSize(); slot++) { +- ItemStack itemStack = this.getInventory().getItem(slot); ++ // Gale start - hoist inventory lookup ++ final SimpleContainer inventory = this.getInventory(); ++ final int containerSize = inventory.getContainerSize(); ++ // Gale end - hoist inventory lookup ++ for (int slot = 0; slot < containerSize; slot++) { ++ ItemStack itemStack = inventory.getItem(slot); + if (!itemStack.isEmpty()) { + Integer value = FOOD_POINTS.get(itemStack.getItem()); + if (value != null) { +@@ -706,7 +_,7 @@ + + for (int count = itemCount; count > 0; count--) { + this.foodLevel = this.foodLevel + value; +- this.getInventory().removeItem(slot, 1); ++ inventory.removeItem(slot, 1); + if (!this.hungry()) { + return; + } +@@ -843,8 +_,14 @@ + } + + private int countFoodPointsInInventory() { ++ // Gale start - avoid stream in villager food check + SimpleContainer inventory = this.getInventory(); +- return FOOD_POINTS.entrySet().stream().mapToInt(entry -> inventory.countItem(entry.getKey()) * entry.getValue()).sum(); ++ int total = 0; ++ for (Map.Entry entry : FOOD_POINTS.entrySet()) { ++ total += inventory.countItem(entry.getKey()) * entry.getValue(); ++ } ++ return total; ++ // Gale end - avoid stream in villager food check + } + + public boolean hasFarmSeeds() { From faea98d8835d9d1dd07c340e4b8dfb25717a8b92 Mon Sep 17 00:00:00 2001 From: Smorki Date: Mon, 3 Aug 2026 16:06:43 +0300 Subject: [PATCH 2/3] Address review: remove inventory hoist, keep stream change --- .../entity/npc/villager/Villager.java.patch | 24 ------------------- 1 file changed, 24 deletions(-) diff --git a/gale-server/minecraft-patches/sources/net/minecraft/world/entity/npc/villager/Villager.java.patch b/gale-server/minecraft-patches/sources/net/minecraft/world/entity/npc/villager/Villager.java.patch index ac1f3b6c..9b9369cf 100644 --- a/gale-server/minecraft-patches/sources/net/minecraft/world/entity/npc/villager/Villager.java.patch +++ b/gale-server/minecraft-patches/sources/net/minecraft/world/entity/npc/villager/Villager.java.patch @@ -1,29 +1,5 @@ --- a/net/minecraft/world/entity/npc/villager/Villager.java +++ b/net/minecraft/world/entity/npc/villager/Villager.java -@@ -697,8 +_,12 @@ - - private void eatUntilFull() { - if (this.hungry() && this.countFoodPointsInInventory() != 0) { -- for (int slot = 0; slot < this.getInventory().getContainerSize(); slot++) { -- ItemStack itemStack = this.getInventory().getItem(slot); -+ // Gale start - hoist inventory lookup -+ final SimpleContainer inventory = this.getInventory(); -+ final int containerSize = inventory.getContainerSize(); -+ // Gale end - hoist inventory lookup -+ for (int slot = 0; slot < containerSize; slot++) { -+ ItemStack itemStack = inventory.getItem(slot); - if (!itemStack.isEmpty()) { - Integer value = FOOD_POINTS.get(itemStack.getItem()); - if (value != null) { -@@ -706,7 +_,7 @@ - - for (int count = itemCount; count > 0; count--) { - this.foodLevel = this.foodLevel + value; -- this.getInventory().removeItem(slot, 1); -+ inventory.removeItem(slot, 1); - if (!this.hungry()) { - return; - } @@ -843,8 +_,14 @@ } From e1933558ebdd151d636dbdc43a585c18a1de9f0b Mon Sep 17 00:00:00 2001 From: Smorki Date: Mon, 3 Aug 2026 19:23:51 +0300 Subject: [PATCH 3/3] Address review: single pass inventory scan, short circuit canBreed, fix comment labels --- .../entity/npc/villager/Villager.java.patch | 27 +++++++++++++++---- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/gale-server/minecraft-patches/sources/net/minecraft/world/entity/npc/villager/Villager.java.patch b/gale-server/minecraft-patches/sources/net/minecraft/world/entity/npc/villager/Villager.java.patch index 9b9369cf..c8905d7b 100644 --- a/gale-server/minecraft-patches/sources/net/minecraft/world/entity/npc/villager/Villager.java.patch +++ b/gale-server/minecraft-patches/sources/net/minecraft/world/entity/npc/villager/Villager.java.patch @@ -1,18 +1,35 @@ --- a/net/minecraft/world/entity/npc/villager/Villager.java +++ b/net/minecraft/world/entity/npc/villager/Villager.java -@@ -843,8 +_,14 @@ +@@ -688,7 +_,9 @@ + + @Override + public boolean canBreed() { +- return this.foodLevel + this.countFoodPointsInInventory() >= 12 && !this.isSleeping() && this.getAge() == 0; ++ // Gale start - Local code optimization - skip inventory scan if food level sufficient ++ return (this.foodLevel >= 12 || this.foodLevel + this.countFoodPointsInInventory() >= 12) && !this.isSleeping() && this.getAge() == 0; ++ // Gale end - Local code optimization - skip inventory scan if food level sufficient + } + + private boolean hungry() { +@@ -843,8 +_,20 @@ } private int countFoodPointsInInventory() { -+ // Gale start - avoid stream in villager food check ++ // Gale start - Local code optimization - single pass food point count SimpleContainer inventory = this.getInventory(); - return FOOD_POINTS.entrySet().stream().mapToInt(entry -> inventory.countItem(entry.getKey()) * entry.getValue()).sum(); + int total = 0; -+ for (Map.Entry entry : FOOD_POINTS.entrySet()) { -+ total += inventory.countItem(entry.getKey()) * entry.getValue(); ++ for (int slot = 0; slot < inventory.getContainerSize(); slot++) { ++ ItemStack itemStack = inventory.getItem(slot); ++ if (!itemStack.isEmpty()) { ++ Integer points = FOOD_POINTS.get(itemStack.getItem()); ++ if (points != null) { ++ total += points * itemStack.getCount(); ++ } ++ } + } + return total; -+ // Gale end - avoid stream in villager food check ++ // Gale end - Local code optimization - single pass food point count } public boolean hasFarmSeeds() {