--- a/net/minecraft/world/level/storage/loot/entries/LootPoolSingletonContainer.java
+++ b/net/minecraft/world/level/storage/loot/entries/LootPoolSingletonContainer.java
@@ -32,6 +_,10 @@
             );
         }
     };
+    // Paper start - Configurable LootPool luck formula
+    private Float lastLuck;
+    private int lastWeight;
+    // Paper end - Configurable LootPool luck formula
 
     protected LootPoolSingletonContainer(int weight, int quality, List<LootItemCondition> conditions, List<LootItemFunction> functions) {
         super(conditions);
@@ -126,7 +_,31 @@
     protected abstract class EntryBase implements LootPoolEntry {
         @Override
         public int getWeight(float luck) {
-            return Math.max(Mth.floor(LootPoolSingletonContainer.this.weight + LootPoolSingletonContainer.this.quality * luck), 0);
+            // Paper start - Configurable LootPool luck formula
+            // SEE: https://luckformula.emc.gs for details and data
+            if (LootPoolSingletonContainer.this.lastLuck != null && LootPoolSingletonContainer.this.lastLuck == luck) {
+                return lastWeight;
+            }
+            // This is vanilla
+            float qualityModifer = (float) LootPoolSingletonContainer.this.quality * luck;
+            double baseWeight = (LootPoolSingletonContainer.this.weight + qualityModifer);
+            if (io.papermc.paper.configuration.GlobalConfiguration.get().misc.useAlternativeLuckFormula) {
+                // Random boost to avoid losing precision in the final int cast on return
+                final int weightBoost = 100;
+                baseWeight *= weightBoost;
+                // If we have vanilla 1, bump that down to 0 so nothing is is impacted
+                // vanilla 3 = 300, 200 basis = impact 2%
+                // =($B2*(($B2-100)/100/100))
+                double impacted = baseWeight * ((baseWeight - weightBoost) / weightBoost / 100);
+                // =($B$7/100)
+                float luckModifier = Math.min(100, luck * 10) / 100;
+                // =B2 - (C2 *($B$7/100))
+                baseWeight = Math.ceil(baseWeight - (impacted * luckModifier));
+            }
+            LootPoolSingletonContainer.this.lastLuck = luck;
+            LootPoolSingletonContainer.this.lastWeight = (int) Math.max(Math.floor(baseWeight), 0);
+            return lastWeight;
+            // Paper end - Configurable LootPool luck formula
         }
     }
 
