⚡ Moteur de performances et régulation des files d'attente
Agrarian Reform est pensé pour les serveurs à forte charge, capable d'absorber des méga-fermes sans pics de latence ni chute de TPS.
📊 Infobox des performances
| Property | Value |
|---|---|
| Global Throttling Budget | CROPS_PER_TICK = 5 |
| Queue Implementation | java.util.concurrent.ConcurrentLinkedQueue |
| Sub-Chunk Palette Filter | hasOnlyAir() & maybeHas(AgrarianCropRules::isCropBlock) |
| Recherche d'eau | Anneaux concentriques de Tchebychev ($r=1 \to \text{maxRange}$, sortie immédiate si eau proche) |
| Optimisation chaussures | Détection immédiate pieds nus ($0.0001\mu\text{s}$, sans interroger les NBT d'enchantements) |
| Journaux de diagnostic | Loggers SLF4J statiques contrôlés par la règle temporaire agrarian_reform:debug_mode |
🧠 Architecture et pipelines d'interception rapide
┌─────────────────────────────────────────────────────────────┐
│ CHUNK LOAD SCAN EVENT │
│ Palette Pre-Filter: section.hasOnlyAir() & maybeHas() │
│ Rejects 85%+ empty non-crop sub-chunks in O(1) time │
└──────────────────────────────┬──────────────────────────────┘
│
▼
┌──────────────────────────────┴──────────────────────────────┐
│ ConcurrentLinkedQueue<CropUpdateTask> │
│ Lock-free thread-safe task buffer │
└──────────────────────────────┬──────────────────────────────┘
│
▼
┌──────────────────────────────┴──────────────────────────────┐
│ ServerTickEvents.END_SERVER_TICK │
│ Polls at most 5 tasks per tick │
│ Updates block states smoothly across consecutive game ticks │
└─────────────────────────────────────────────────────────────┘Pourquoi 5 cultures par tick ?
Si un joueur recharge après 24 heures une exploitation contenant 10 000 cultures, appliquer 10 000 mises à jour de blocs en un seul tick provoquerait un gel serveur de plus de 1000 ms.
En échelonnant les calculs à un rythme fluide de 5 cultures par tick :
- Le serveur conserve ses 20 TPS constants pendant le chargement des chunks.
- Les 10 000 cultures se mettent à niveau en douceur en 2 000 ticks (~100 secondes) en arrière-plan sans perturber le jeu.
🏎️ Optimisations algorithmiques centrales
- Filtrage par palette de sous-chunks : Au lieu d'analyser $98,304$ blocs,
CropScannerinterroge la palette de chaque section $16 \times 16 \times 16$. Sans cultures présentes, la section est ignorée en $0.0001\mu\text{s}$. - Balayage concentrique de Tchebychev : L'eau est recherchée de l'intérieur vers l'extérieur ($r = 1 \to \text{maxRange}$). L'eau étant généralement adjacente ($r=1$), le test s'arrête au premier anneau.
- Test rapide pieds nus : Lors d'un contact avec le sol,
hasSoftStep()vérifie si les pieds sont nus. Si c'est le cas, la lecture des NBT d'enchantements est évitée. - Arrêt immédiat à maturité : En boucle accélérée, le processus s'interrompt aussitôt la maturité maximale atteinte.
💾 Garanties de 0 écriture sur disque
- Survol en lecture seule : Le scan initial ne modifie jamais les blocs et conserve le drapeau
unsavedàfalse. - Mutation sélective : Dans
ContinuumManager.processCropUpdate,level.setBlock()est uniquement appelé si $\Delta \text{age} > 0$. - Protection anti-écriture disque : Les chunks intacts conservent
unsaved == false, évitant toute sérialisation NBT et écriture disque ($0\text{ I/O disque}$).
See also: Le Continuum (Croissance hors-ligne), Hydrodynamique et irrigation, and Architecture et cibles Mixin.
