Skip to content

Mega-Stapel-Aggregationsmechanik (MC 26.1.2)

Dieses Dokument liefert eine technische und mathematische Aufschlüsselung der Item-Aggregation am Boden, der Suchradius-Mathematik und der Entitätsverschmelzung in Item Clumps für Minecraft 26.1.2.


📊 Feature-Infobox

EigenschaftSpezifikation
SystemnameMega-Stapel-Aggregator für Boden-Items
Zielklassenet.minecraft.world.entity.item.ItemEntity
Standard-Verschmelzungslimit9.999 Items (Konfigurierbar bis $2.147.483.647$)
Suchradius ($r$)Horizontal $1\text{ bis }10\text{ Blöcke}$ (Standard: $1\text{ Block}$)
Radius-Injektion@ModifyArgs auf AABB.inflate(DDD)
Steuernde GameRulesitem_clumps:enable_clumping, item_clumps:max_clump_size, item_clumps:merge_radius

⚙️ Funktionsweise der Mega-Stapel-Aggregation

In Vanilla Minecraft suchen gedroppte Items jeden Tick via mergeWithNeighbours() nach gleichen Items. Vanilla untersagt das Verschmelzen jedoch, wenn die Anzahl itemStack.getMaxStackSize() (meist 64) überschreiten würde.

Item Clumps hebt diese Beschränkung über ItemEntityMixin.java auf, während die Datenkomponentenintegrität strikt gewahrt bleibt.

                  ┌──────────────────────────────┐
                  │    ItemEntity A Ticks In     │
                  └──────────────┬───────────────┘


                  ┌──────────────────────────────┐
                  │     Feasibility Check        │
                  │  - Matching player target?   │
                  │  - Identical DataComponents? │
                  └──────────────┬───────────────┘
                                 │ (Pass)

                  ┌──────────────────────────────┐
                  │   Combine Stacks Math Check  │
                  └──────────────┬───────────────┘

                 ┌───────────────┴───────────────┐
                 │                               │
    thisCount + otherCount <= maxClump    thisCount + otherCount > maxClump
                 │                               │
                 ▼                               ▼
       ┌───────────────────┐           ┌───────────────────┐
       │   Complete Merge  │           │   Partial Merge   │
       │ Larger absorbs    │           │ Fill entity A to  │
       │ smaller entity;   │           │ maxClumpSize;     │
       │ Younger age kept. │           │ B keeps remainder.│
       └───────────────────┘           └───────────────────┘

📐 Mathematische Formeln & Präzisionsberechnungen

1. Horizontale Bounding-Box-Vergrößerung (@ModifyArgs)

$$\text{args.set}(0, r), \quad \text{args.set}(2, r)$$

Wobei:

  • $r = \text{DynamicGameRuleManager}.\text{getInt}(\text{level}, \text{MERGE_RADIUS}) \in [1, 10]$ Blöcke.
  • Der vertikale Höhenindex ($1$) bleibt unverändert, wodurch die Trennung zwischen verschiedenen Stockwerken gewahrt bleibt.

2. Mathematik des Itemmengen-Transfers

  • Vollständige Absorption ($S \le \text{maxClumpSize}$): $$\text{count}_{\text{merged}} = \text{thisCount} + \text{otherCount}$$
  • Partielle Absorption ($S > \text{maxClumpSize}$): $$\Delta = \text{maxClumpSize} - \text{thisCount}$$ $$\text{thisCount}' = \text{maxClumpSize}, \quad \text{otherCount}' = \text{otherCount} - \Delta$$

💻 Reale Java-Quellcode-Implementierung

Aus ItemEntityMixin.java in Minecraft 26.1.2:

java
@ModifyArgs(method = "mergeWithNeighbours", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/phys/AABB;inflate(DDD)Lnet/minecraft/world/phys/AABB;"))
private void item_clumps$modifySearchRadius(Args args) {
    if (DynamicGameRuleManager.getBoolean(this.level(), ItemClumpsFabric.ENABLE_CLUMPING)) {
        double radius = DynamicGameRuleManager.getInt(this.level(), ItemClumpsFabric.MERGE_RADIUS);
        args.set(0, radius);
        args.set(2, radius);
    }
}

@Inject(method = "tryToMerge", at = @At("HEAD"), cancellable = true)
private void item_clumps$customMerge(ItemEntity other, CallbackInfo ci) {
    if (!DynamicGameRuleManager.getBoolean(this.level(), ItemClumpsFabric.ENABLE_CLUMPING)) return;

    ItemStack thisStack = this.getItem();
    ItemStack otherStack = other.getItem();

    if (!Objects.equals(this.target, ((ItemEntityMixin)(Object)other).target) || 
        !ItemStack.isSameItemSameComponents(thisStack, otherStack)) {
        return;
    }

    int thisCount = thisStack.getCount();
    int otherCount = otherStack.getCount();
    int maxClump = DynamicGameRuleManager.getInt(this.level(), ItemClumpsFabric.MAX_CLUMP_SIZE);

    if (thisCount + otherCount > maxClump) {
        int spaceLeft = maxClump - thisCount;
        if (spaceLeft > 0) {
            thisStack.setCount(maxClump);
            this.setItem(thisStack);
            otherStack.setCount(otherCount - spaceLeft);
            other.setItem(otherStack);
        }
        ci.cancel();
        return;
    }

    // Full Merge: larger stack absorbs the smaller stack
    if (otherCount < thisCount) {
        thisStack.setCount(thisCount + otherCount);
        this.setItem(thisStack);
        this.pickupDelay = Math.max(this.pickupDelay, ((ItemEntityMixin)(Object)other).pickupDelay);
        this.age = Math.min(this.age, ((ItemEntityMixin)(Object)other).age);
        other.discard();
    } else {
        otherStack.setCount(thisCount + otherCount);
        other.setItem(otherStack);
        ((ItemEntityMixin)(Object)other).pickupDelay = Math.max(((ItemEntityMixin)(Object)other).pickupDelay, this.pickupDelay);
        ((ItemEntityMixin)(Object)other).age = Math.min(((ItemEntityMixin)(Object)other).age, this.age);
        this.discard();
    }
    ci.cancel();
}

🔗 Verwandte Dokumentation (MC 26.1.2)

Official documentation & web portal for Dasik Igaijinn mods.