Skip to content

⏳ Das Kontinuum: Offline-Pflanzenpersistenz-Engine

Das Kontinuum (The Continuum) ist das Flaggschiff-Simulationssystem. In Vanilla stoppt das Wachstum beim Entladen von Chunks. The Continuum speichert Zeitstempel und simuliert das Offline-Wachstum flüssig beim Neuladen.


📊 Technische Spezifikationen Infobox

ComponentSpecification
Engine Classnet.instantgratification.agrarianreform.continuum.ContinuumManager
Data Handlernet.instantgratification.agrarianreform.continuum.ContinuumData
Scanner Helpernet.instantgratification.agrarianreform.continuum.CropScanner
Saved Data IDagrarian_reform_continuum (Dimension-scoped SavedDataType)
AktualisierungsbudgetCROPS_PER_TICK = 5 (Gedrosselte globale Warteschlange)
Palette Pre-Filtersection.hasOnlyAir() & section.maybeHas(AgrarianCropRules::isCropBlock)
Zeitstempel-ObergrenzeEinträge älter als 30 Echtzeittage ($51,840,000\text{ Ticks}$) werden bereinigt
Unterstützte PflanzenAlle Nutzpflanzen, Zuckerrohr, Kakteen, Netherwarzen, Kakao, Ranken, Setzlinge, Beeren

⚙️ Funktionsweise des Kontinuums

┌─────────────────────────────────────────────────────────────┐
│                     CHUNK UNLOAD EVENT                      │
│ ServerChunkEvents.CHUNK_UNLOAD records server game time pos │
│ Saved to world storage via ContinuumData (SavedDataType)    │
└──────────────────────────────┬──────────────────────────────┘

                               ▼ (Offline / World Unloaded Time Delta)
┌──────────────────────────────┴──────────────────────────────┐
│                      CHUNK LOAD EVENT                       │
│ ServerChunkEvents.CHUNK_LOAD retrieves unload timestamp     │
│ Calculates timeDelta = currentTick - unloadTick             │
└──────────────────────────────┬──────────────────────────────┘


┌──────────────────────────────┴──────────────────────────────┐
│             SUB-CHUNK PALETTE-GATED SCANNER                 │
│ CropScanner skips empty air & non-crop sections (O(1))      │
│ Queues matching plants into ConcurrentLinkedQueue            │
└──────────────────────────────┬──────────────────────────────┘


┌──────────────────────────────┴──────────────────────────────┐
│            THROTTLED PER-CROP TICK PROCESSOR                │
│ ServerTickEvents.END_SERVER_TICK processes 5 crops/tick     │
│ Scales delta per-crop via AgrarianCropRules & updates state │
└─────────────────────────────────────────────────────────────┘

📐 Mathematische Berechnungsformeln

$$\Delta t_{\text{effective}} = \begin{cases} 0 & \text{if } M_{\text{crop}} \le 0 \ \left\lfloor \frac{\Delta t \cdot M_{\text{crop}}}{100} \right\rfloor & \text{if } M_{\text{crop}} > 0 \end{cases}$$

1. Standard-Pflanzen (CropBlock & Mod-Pflanzen)

$$S = \text{CropScanner.getSpeed}(\text{crop}, \text{level}, \text{pos})$$ $$T_{\text{stage}} = \left( \frac{25.0}{S} + 1.0 \right) \cdot \frac{4096.0}{3.0}$$ $$\Delta \text{age} = \left\lfloor \frac{\Delta t_{\text{effective}}}{T_{\text{stage}}} \right\rfloor$$

2. Zuckerrohr- und Kakteenhöhe

$$\Delta \text{age} = \left\lfloor \frac{\Delta t_{\text{effective}}}{1365} \right\rfloor$$

3. Intervalle für weitere Pflanzen

PflanzenartTicks pro StufeWahrscheinlichkeit pro TickMax. Stufe
Netherwarze13,650 Ticks (~11.37 Min.)10% pro ZufallstickStufe 3
Kakaobohnen6,825 Ticks (~5.68 Min.)20% pro ZufallstickStufe 2
Süßbeeren6,825 Ticks (~5.68 Min.)20% pro ZufallstickStufe 3
Ranken13,650 Ticks (~11.37 Min.)10% pro ZufallstickWachstum abwärts
Setzlinge95,550 Ticks (~79.6 Min.)1.4% pro ZufallstickStufe 2 (Baumwachstum)

⚡ Leistungsoptimierungen

1. Sub-Chunk Palette-Level Pre-Filtering

Statt alle $98.304$ Blockkoordinaten zu scannen, prüft CropScanner die Paletten jeder $16 \times 16 \times 16$ LevelChunkSection:

  1. section.hasOnlyAir(): Überspringt leere Sub-Chunks in $0.0001\mu\text{s}$.
  2. section.maybeHas(AgrarianCropRules::isCropBlock): Prüft Paletten direkt. Gibt es keine Pflanzen, werden 4.096 Blöcke sofort übersprungen. Dadurch werden 85% bis 95% nichtlandwirtschaftlicher Abschnitte ohne Rechenaufwand ignoriert.

2. Bereinigung veralteter Zeitstempel nach 30 Tagen

$$\text{Max Timestamp Age} = 30\text{ days} \times 86,400\text{ s/day} \times 20\text{ ticks/s} = 51,840,000\text{ ticks}$$ Beim regelmäßigen Speichern (BEFORE_SAVE) werden Einträge älter als 30 Tage aus Speicher und Dateien entfernt.


💾 Chunk-Persistenz & Null-Festplatten-Schreibschutz

  1. Entkoppelte Zeitstempel: Zeitstempel liegen in ContinuumData, sodass LevelChunk.unsaved auf false bleibt.
  2. Reine Lese-Scans: Blockprüfungen über Paletten markieren Chunks niemals als modifiziert.
  3. Bedingtes Schreiben: setBlock() wird nur bei echtem Fortschritt ($\Delta \text{age} > 0$) aufgerufen ($0\text{ Festplatten-I/O}$).

See also: Leistung und Warteschlangen-Drosselung, Pflanzenregister und universelle Feldfrüchte, and Architektur und Mixin-Ziele.

Official documentation & web portal for Dasik Igaijinn mods.