Builder class

Пакет: com.hypixel.hytale.builtin.hytalegenerator.engine.chunkgenerator

Файл: com/hypixel/hytale/builtin/hytalegenerator/engine/chunkgenerator/StagedChunkGenerator.java

Поля (51)

МодификаторыТипИмя
public final BufferType ENTITY_OUTPUT_BUFFER_TYPE
public final ParametrizedBufferType ENVIRONMENT_OUTPUT_BUFFER_TYPE
public final ParametrizedBufferType MATERIAL_OUTPUT_BUFFER_TYPE
public final ParametrizedBufferType TINT_OUTPUT_BUFFER_TYPE
private double bufferCapacityFactor
private final Map<String, StagedChunkGenerator.ExecutorTier> concurrencyTiers
private MaterialCache materialCache
private String profiledExecutorKey
private PositionProvider spawnPositions
private final List<Stage> stages
private IntSet statsCheckpoints
private String statsHeader
private double targetPlayerCount
private double targetViewDistance
StagedChunkGenerator var1
Int2ObjectMap var1
Set var1
Bounds3i var1
double var10
double var12
var12
var12
Bounds3i var12
Bounds3i var13
double var14
Bounds3i var14
Bounds3i var15
double var16
double var18
Set var2
Stage var2
Bounds3i[] var2
double var20
Int2ObjectMap var3
IntList var3
IntList var3
int var3
Stage var3
List var4
IntListIterator var4
Bounds3i var4
Bounds3i var4
int var5
Stage var5
BufferType var6
List var6
Vector3i var7
Stage var8
double var8
Stage var8
Map var9

Методы (28)

МодификаторыВозвратСигнатура
public StagedChunkGenerator.Builder addExecutorTierpublic StagedChunkGenerator.Builder addExecutorTier(@Nonnull String var1, @Nonnull StagedChunkGenerator.ExecutorTier var2)
public StagedChunkGenerator.Builder appendStagepublic StagedChunkGenerator.Builder appendStage(@Nonnull Stage var1)
public StagedChunkGenerator buildpublic StagedChunkGenerator build()
private static int calculateCapacityFromBoundsprivate static int calculateCapacityFromBounds(@Nonnull Bounds3i var0, double var1, double var3, double var5)
abstract return calculateCapacityFromBoundsreturn calculateCapacityFromBounds(var4, this.bufferCapacityFactor, this.targetViewDistance, this.targetPlayerCount)
private Set<BufferType> createListOfAllBufferTypesprivate Set<BufferType> createListOfAllBufferTypes()
private Int2ObjectMap<IntSet> createStageDependencyMapprivate Int2ObjectMap<IntSet> createStageDependencyMap()
private IntList createStagesThatReadFromprivate IntList createStagesThatReadFrom(int var1)
private Bounds3i[] createTotalOutputBoundsArrayprivate Bounds3i[] createTotalOutputBoundsArray(@Nonnull Int2ObjectMap<IntSet> var1)
private void createTotalOutputBoundsForStageprivate void createTotalOutputBoundsForStage(int var1, @Nonnull Int2ObjectMap<IntSet> var2, @Nonnull Bounds3i[] var3)
for for(BufferType var5 : var2)
for for(Bounds3i var3 : var0)
abstract for for(int var5 = 0; var5 < var4.size()
abstract for for(int var7 = 0; var7 < this.stages.size()
abstract for for(int var2 = 0; var2 < this.stages.size()
abstract for for(int var6 = 0; var6 < this.stages.size()
abstract for for(int var16 = 1; var16 < var6.size()
private static Bounds3i getEncompassingBoundsprivate static Bounds3i getEncompassingBounds(@Nonnull Collection<Bounds3i> var0)
if if(var3 >= var2.length)
if if(var7.x == 1 && var7.z == 1)
if if(var12 != null)
private boolean isGeneratorOutputBufferTypeprivate boolean isGeneratorOutputBufferType(@Nonnull BufferType var1)
private int resolveBufferCapacityprivate int resolveBufferCapacity(@Nonnull BufferType var1, @Nonnull Bounds3i[] var2)
public StagedChunkGenerator.Builder setProfiledExecutorKeypublic StagedChunkGenerator.Builder setProfiledExecutorKey(@Nonnull String var1)
public StagedChunkGenerator.Builder withBufferCapacitypublic StagedChunkGenerator.Builder withBufferCapacity(double var1, double var3, double var5)
public StagedChunkGenerator.Builder withMaterialCachepublic StagedChunkGenerator.Builder withMaterialCache(@Nonnull MaterialCache var1)
public StagedChunkGenerator.Builder withSpawnPositionspublic StagedChunkGenerator.Builder withSpawnPositions(@Nonnull PositionProvider var1)
public StagedChunkGenerator.Builder withStatspublic StagedChunkGenerator.Builder withStats(@Nonnull String var1, @Nonnull IntSet var2)

Исходный код

Показать/скрыть
class="kw">package com.hypixel.hytale.builtin.hytalegenerator.engine.chunkgenerator;

class="kw">import com.hypixel.hytale.builtin.hytalegenerator.ArrayUtil;
class="kw">import com.hypixel.hytale.builtin.hytalegenerator.FutureUtils;
class="kw">import com.hypixel.hytale.builtin.hytalegenerator.GridUtils;
class="kw">import com.hypixel.hytale.builtin.hytalegenerator.LoggerUtil;
class="kw">import com.hypixel.hytale.builtin.hytalegenerator.bounds.Bounds3i;
class="kw">import com.hypixel.hytale.builtin.hytalegenerator.engine.bufferbundle.BufferBundle;
class="kw">import com.hypixel.hytale.builtin.hytalegenerator.engine.bufferbundle.buffers.EntityBuffer;
class="kw">import com.hypixel.hytale.builtin.hytalegenerator.engine.bufferbundle.buffers.SimplePixelBuffer;
class="kw">import com.hypixel.hytale.builtin.hytalegenerator.engine.bufferbundle.buffers.VoxelBuffer;
class="kw">import com.hypixel.hytale.builtin.hytalegenerator.engine.bufferbundle.buffers.type.BufferType;
class="kw">import com.hypixel.hytale.builtin.hytalegenerator.engine.bufferbundle.buffers.type.ParametrizedBufferType;
class="kw">import com.hypixel.hytale.builtin.hytalegenerator.engine.performanceinstruments.HierarchicalTimingProfiler;
class="kw">import com.hypixel.hytale.builtin.hytalegenerator.engine.stages.Stage;
class="kw">import com.hypixel.hytale.builtin.hytalegenerator.engine.views.EntityBufferView;
class="kw">import com.hypixel.hytale.builtin.hytalegenerator.engine.views.PixelBufferView;
class="kw">import com.hypixel.hytale.builtin.hytalegenerator.engine.views.VoxelBufferView;
class="kw">import com.hypixel.hytale.builtin.hytalegenerator.material.FluidMaterial;
class="kw">import com.hypixel.hytale.builtin.hytalegenerator.material.Material;
class="kw">import com.hypixel.hytale.builtin.hytalegenerator.material.MaterialCache;
class="kw">import com.hypixel.hytale.builtin.hytalegenerator.material.SolidMaterial;
class="kw">import com.hypixel.hytale.builtin.hytalegenerator.positionproviders.PositionProvider;
class="kw">import com.hypixel.hytale.builtin.hytalegenerator.voxelspace.VoxelSpace;
class="kw">import com.hypixel.hytale.builtin.hytalegenerator.workerindexer.WorkerIndexer;
class="kw">import com.hypixel.hytale.component.ComponentType;
class="kw">import com.hypixel.hytale.component.Holder;
class="kw">import com.hypixel.hytale.math.util.ChunkUtil;
class="kw">import com.hypixel.hytale.math.vector.Vector3iUtil;
class="kw">import com.hypixel.hytale.server.core.asset.type.blocktype.config.BlockType;
class="kw">import com.hypixel.hytale.server.core.blocktype.component.BlockPhysics;
class="kw">import com.hypixel.hytale.server.core.universe.world.chunk.environment.EnvironmentChunk;
class="kw">import com.hypixel.hytale.server.core.universe.world.chunk.section.FluidSection;
class="kw">import com.hypixel.hytale.server.core.universe.world.storage.ChunkStore;
class="kw">import com.hypixel.hytale.server.core.universe.world.worldgen.GeneratedBlockChunk;
class="kw">import com.hypixel.hytale.server.core.universe.world.worldgen.GeneratedChunk;
class="kw">import com.hypixel.hytale.server.core.universe.world.worldgen.GeneratedEntityChunk;
class="kw">import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
class="kw">import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
class="kw">import it.unimi.dsi.fastutil.ints.IntArrayList;
class="kw">import it.unimi.dsi.fastutil.ints.IntList;
class="kw">import it.unimi.dsi.fastutil.ints.IntListIterator;
class="kw">import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
class="kw">import it.unimi.dsi.fastutil.ints.IntSet;
class="kw">import java.util.ArrayList;
class="kw">import java.util.Collection;
class="kw">import java.util.HashMap;
class="kw">import java.util.HashSet;
class="kw">import java.util.List;
class="kw">import java.util.Map;
class="kw">import java.util.Set;
class="kw">import java.util.Map.Entry;
class="kw">import java.util.concurrent.CompletableFuture;
class="kw">import java.util.concurrent.ExecutorService;
class="kw">import javax.annotation.Nonnull;
class="kw">import javax.annotation.Nullable;
class="kw">import org.joml.Vector3d;
class="kw">import org.joml.Vector3i;

class="kw">public class StagedChunkGenerator class="kw">implements ChunkGenerator {
   class="kw">public class="kw">static class="kw">final int WORLD_MIN_Y_BUFFER_GRID = 0;
   class="kw">public class="kw">static class="kw">final int WORLD_MAX_Y_BUFFER_GRID = 40;
   class="kw">public class="kw">static class="kw">final int WORLD_HEIGHT_BUFFER_GRID = 40;
   @Nonnull
   class="kw">public class="kw">static class="kw">final Bounds3i CHUNK_BOUNDS_BUFFER_GRID = new Bounds3i(Vector3iUtil.ZERO, new Vector3i(4, 40, 4));
   @Nonnull
   class="kw">public class="kw">static class="kw">final Bounds3i SINGLE_BUFFER_TILE_BOUNDS_BUFFER_GRID = new Bounds3i(
      new Vector3i(0, 0, 0), new Vector3i(VoxelBuffer.SIZE.x, 320, VoxelBuffer.SIZE.x)
   );
   class="kw">private BufferType materialOutput_bufferType;
   class="kw">private BufferType tintOutput_bufferType;
   class="kw">private BufferType environmentOutput_bufferType;
   class="kw">private BufferType entityOutput_bufferType;
   class="kw">private Stage[] stages;
   class="kw">private Bounds3i[] stagesOutputBounds_bufferGrid;
   class="kw">private BufferBundle bufferBundle;
   class="kw">private MaterialCache materialCache;
   class="kw">private PositionProvider spawnPositions;
   class="kw">private Map<String, StagedChunkGenerator.ExecutorTier> executorTiers;
   class="kw">private String profiledExecutorKey;
   class="kw">private HierarchicalTimingProfiler hierarchicalTimingProfiler;
   class="kw">private IntSet statsCheckpoints;
   class="kw">private int generatedChunkCount;
   class="kw">private long totalCacheBufferRequests;
   class="kw">private long missedCacheBufferRequests;

   class="kw">private StagedChunkGenerator() {
   }

   @Nullable
   @Override
   class="kw">public GeneratedChunk generate(@Nonnull ChunkRequest.Arguments var1, @Nonnull String var2) {
      if (var1.stillNeeded() != null && !var1.stillNeeded().test(var1.index())) {
         class="kw">return null;
      }

      boolean var3 = this.profiledExecutorKey.equals(var2);
      if (var3) {
         this.generatedChunkCount++;
      }

      HierarchicalTimingProfiler.Probe var4 = new HierarchicalTimingProfiler.Probe("Total").start(var3);
      HierarchicalTimingProfiler.Probe var5 = var4.createProbe("Content Generation").start(var3);
      HierarchicalTimingProfiler.Probe var6 = var5.createProbe("Access Initialization").start(var3);
      Bounds3i var7 = GridUtils.createChunkBounds_bufferGrid(var1.x(), var1.z());
      Map var8 = this.createAccesses(var7);
      var6.stop(var3);
      StagedChunkGenerator.ExecutorTier var9 = this.executorTiers.get(var2);
      if (var9 == null) {
         throw new IllegalArgumentException("Invalid concurrency key provided: " + var2);
      }

      WorkerIndexer var10 = var9.workerIndexer();
      ExecutorService var11 = var9.executor();

      for (int var12 = 0; var12 < this.stages.length; var12++) {
         HierarchicalTimingProfiler.Probe var13 = var5.createProbe(this.stages[var12].getName() + " (Stage " + var12 + ")").start(var3);
         HierarchicalTimingProfiler.Probe var14 = var13.createProbe("Preparation").start(var3);
         int var15 = var12;
         Stage var16 = this.stages[var12];
         List var17 = var16.getOutputTypes();
         List var18 = new ArrayList<>(var17.size());

         for (BufferType var20 : var17) {
            BufferBundle.Grid var21 = this.bufferBundle.getGrid(var20);
            var18.add(var21);
         }

         Bounds3i var37 = this.stagesOutputBounds_bufferGrid[var15].clone();
         var37.stack(CHUNK_BOUNDS_BUFFER_GRID);
         var37.offset(var7.min);
         List var38 = new ArrayList<>();
         Vector3i var39 = new Vector3i(0, 0, 0);

         for (var39.x = var37.min.x; var39.x < var37.max.x; var39.x++) {
            for (var39.z = var37.min.z; var39.z < var37.max.z; var39.z++) {
               this.totalCacheBufferRequests++;
               boolean var22 = true;

               for (BufferBundle.Grid var24 : var18) {
                  BufferBundle.Access var25 = var8.get(var24.getBufferType());
                  if (!isColumnCached(var25, var39, var12)) {
                     var22 = false;
                     break;
                  }
               }

               if (!var22) {
                  this.missedCacheBufferRequests++;
                  var38.add(new Vector3i(var39));
               }
            }
         }

         List var40 = ArrayUtil.split(var38, var10.getWorkerCount());
         WorkerIndexer.Session var41 = var10.createSession();
         List var42 = new ArrayList<>();

         for (int var43 = 0; var43 < var40.size(); var43++) {
            List var26 = var40.get(var43);
            WorkerIndexer.Id var27 = var41.next();
            List var28 = new ArrayList<>(var26.size());

            for (int var29 = 0; var29 < var26.size(); var29++) {
               Vector3i var30 = var26.get(var29);
               Runnable var31 = this.createTileTask(var15, var30, var27, var8);
               var28.add(var31);
            }

            var42.add(var28);
         }

         var14.stop(var3);
         HierarchicalTimingProfiler.Probe var44 = var13.createProbe("Execution").start(var3);
         HierarchicalTimingProfiler.Probe var45 = var44.createProbe("Async Processes Start").start(var3);
         List var46 = new ArrayList<>();

         for (List var48 : var42) {
            CompletableFuture var49 = CompletableFuture.runAsync(() -> {
               for (Runnable var2 : var48) {
                  var2.run();
               }
            }, var11).handle((var1x, var2x) -> {
               if (var2x == null) {
                  class="kw">return null;
               }

               LoggerUtil.logException("during async execution of stage " + var16, var2x);
               class="kw">return null;
            });
            var46.add(var49);
         }

         var45.stop(var3);
         FutureUtils.allOf(var46).join();
         var44.stop(var3);
         var13.stop(var3);
      }

      var5.stop(var3);
      HierarchicalTimingProfiler.Probe var32 = var4.createProbe("Data Transfer").start(var3);
      GeneratedChunk var33 = new GeneratedChunk(
         new GeneratedBlockChunk(var1.index(), var1.x(), var1.z()), new GeneratedEntityChunk(), GeneratedChunk.makeSections()
      );
      List var34 = new ArrayList<>();
      var34.add(this.transferMaterials(var1, var33, var32, var9, var3));
      var34.add(this.transferEnvironments(var1, var33, var32, var9, var3));
      var34.add(this.transferTints(var1, var33, var32, var9, var3));
      var34.add(this.transferEntities(var1, var33, var32, var9, var3));
      var34.add(this.transferBlockStates(var1, var33, var32, var9, var3));
      FutureUtils.allOf(var34).join();
      var32.stop(var3);
      var4.stop(var3);
      this.hierarchicalTimingProfiler.takeSample(var4, var3);
      if (var3 && this.statsCheckpoints.contains(this.generatedChunkCount)) {
         BufferBundle.MemoryReport var35 = this.bufferBundle.createMemoryReport();
         StringBuilder var36 = new StringBuilder();
         var36.append(this.hierarchicalTimingProfiler.toString())
            .append(var35.toString())
            .append(this.createContextDependencyReport(0))
            .append(this.createBufferRequestCacheReport());
         LoggerUtil.getLogger().info(var36.toString());
      }

      this.bufferBundle.closeALlAccesses();
      class="kw">return var33;
   }

   @Nonnull
   @Override
   class="kw">public PositionProvider getSpawnPositions() {
      class="kw">return this.spawnPositions;
   }

   @Nonnull
   class="kw">private Map<BufferType, BufferBundle.Access> createAccesses(@Nonnull Bounds3i var1) {
      Map var2 = new HashMap<>();

      for (int var3 = 0; var3 < this.stages.length; var3++) {
         Stage var4 = this.stages[var3];
         List var5 = var4.getOutputTypes();
         Bounds3i var6 = this.stagesOutputBounds_bufferGrid[var3].clone();
         var6.stack(CHUNK_BOUNDS_BUFFER_GRID);
         var6.offset(var1.min);

         for (BufferType var8 : var5) {
            BufferBundle.Access var9 = this.bufferBundle.createBufferAccess(var8, var6);
            var2.put(var8, var9);
         }
      }

      class="kw">return var2;
   }

   @Nonnull
   class="kw">private Runnable createTileTask(int var1, @Nonnull Vector3i var2, @Nonnull WorkerIndexer.Id var3, @Nonnull Map<BufferType, BufferBundle.Access> var4) {
      Stage var5 = this.stages[var1];
      Map var6 = var5.getInputTypesAndBounds_bufferGrid();
      List var7 = var5.getOutputTypes();
      int var8 = var6.size() + var7.size();
      Stage.Context var9 = new Stage.Context(new HashMap<>(var8), var3);

      for (Entry var11 : var6.entrySet()) {
         BufferType var12 = var11.getKey();
         Bounds3i var13 = var11.getValue().clone().offset(var2);
         BufferBundle.Access.View var14 = var4.get(var12).createView(var13);
         var9.bufferAccess.put(var12, var14);
      }

      for (BufferType var17 : var5.getOutputTypes()) {
         assert !var9.bufferAccess.containsKey(var17);
         Bounds3i var18 = GridUtils.createColumnBounds_bufferGrid(var2, 0, 40);
         BufferBundle.Access.View var19 = var4.get(var17).createView(var18);
         var9.bufferAccess.put(var17, var19);
      }

      Vector3i var16 = new Vector3i(var2);
      class="kw">return () -> {
         try {
            var5.run(var9);
         } class="kw">finally {
            for (BufferType var9 : var5.getOutputTypes()) {
               updateTrackersForColumn(var1, var4.get(var9).createView(), var16);
            }
         }
      };
   }

   @Nonnull
   class="kw">private CompletableFuture<Void> transferBlockStates(
      @Nonnull ChunkRequest.Arguments var1,
      @Nonnull GeneratedChunk var2,
      @Nonnull HierarchicalTimingProfiler.Probe var3,
      @Nonnull StagedChunkGenerator.ExecutorTier var4,
      boolean var5
   ) {
      Bounds3i var6 = GridUtils.createChunkBounds_voxelGrid(var1.x(), var1.z());
      Bounds3i var7 = GridUtils.createChunkBounds_bufferGrid(var1.x(), var1.z());
      BufferBundle.Access var8 = this.bufferBundle.createBufferAccess(this.materialOutput_bufferType, var7);
      VoxelSpace var9 = new VoxelBufferView<>(var8.createView(), Material.class);
      HierarchicalTimingProfiler.Probe var10 = var3.createProbe("Block States");
      class="kw">return CompletableFuture.runAsync(() -> {
         var10.start(var5);
         Vector3i var5 = new Vector3i();

         for (var5.x = var6.min.x; var5.x < var6.max.x; var5.x++) {
            for (var5.z = var6.min.z; var5.z < var6.max.z; var5.z++) {
               for (var5.y = var6.min.y; var5.y < var6.max.y; var5.y++) {
                  SolidMaterial var6 = var9.get(var5).solid();
                  if (var6 != null && var6.holder != null) {
                     var2.setState(var5.x, var5.y, var5.z, var6.holder);
                  }
               }
            }
         }

         var10.stop(var5);
      }, var4.executor()).handle((var0, var1x) -> {
         if (var1x == null) {
            class="kw">return null;
         }

         LoggerUtil.logException("a HytaleGenerator async process", var1x, LoggerUtil.getLogger());
         class="kw">return null;
      });
   }

   @Nonnull
   class="kw">private CompletableFuture<Void> transferMaterials(
      @Nonnull ChunkRequest.Arguments var1,
      @Nonnull GeneratedChunk var2,
      @Nonnull HierarchicalTimingProfiler.Probe var3,
      @Nonnull StagedChunkGenerator.ExecutorTier var4,
      boolean var5
   ) {
      Bounds3i var6 = GridUtils.createChunkBounds_voxelGrid(var1.x(), var1.z());
      Bounds3i var7 = GridUtils.createChunkBounds_bufferGrid(var1.x(), var1.z());
      BufferBundle.Access var8 = this.bufferBundle.createBufferAccess(this.materialOutput_bufferType, var7);
      VoxelSpace var9 = new VoxelBufferView<>(var8.createView(), Material.class);
      GeneratedBlockChunk var10 = var2.getBlockChunk();
      Holder[] var11 = var2.getSections();
      ComponentType var12 = FluidSection.getComponentType();
      CompletableFuture[] var13 = new CompletableFuture[10];

      for (int var14 = 0; var14 < 10; var14++) {
         int var15 = var14;
         FluidSection var16 = var11[var14].ensureAndGetComponent(var12);
         HierarchicalTimingProfiler.Probe var17 = var3.createProbe("Materials Section " + var15);
         CompletableFuture var18 = CompletableFuture.runAsync(() -> {
            var17.start(var5);
            int var9 = var15 * 32;
            int var10 = var9 + 32;

            for (int var11 = 0; var11 < 32; var11++) {
               int var12 = var11 + var6.min.x;

               for (int var13 = 0; var13 < 32; var13++) {
                  int var14 = var13 + var6.min.z;

                  for (int var15 = var9; var15 < var10; var15++) {
                     int var16 = var15 - var9;
                     Material var17 = var9.get(var12, var15 + var6.min.y, var14);
                     if (var17 != null && var17 != this.materialCache.EMPTY) {
                        SolidMaterial var18 = var17.solid();
                        FluidMaterial var19 = var17.fluid();
                        var10.setBlock(var11, var15, var13, var18.blockId, var18.rotation, var18.filler);
                        setSupport(var2, var11, var15, var13, var18.blockId, var18.support);
                        var16.setFluid(var11, var16, var13, var19.fluidId, var19.fluidLevel);
                     }
                  }
               }
            }

            var17.stop(var5);
         }, var4.executor).handle((var0, var1x) -> {
            if (var1x == null) {
               class="kw">return null;
            }

            LoggerUtil.logException("a HytaleGenerator async process", var1x, LoggerUtil.getLogger());
            class="kw">return null;
         });
         var13[var14] = var18;
      }

      class="kw">return CompletableFuture.allOf(var13).thenRun(var10::generateHeight);
   }

   @Nonnull
   class="kw">private CompletableFuture<Void> transferTints(
      @Nonnull ChunkRequest.Arguments var1,
      @Nonnull GeneratedChunk var2,
      @Nonnull HierarchicalTimingProfiler.Probe var3,
      @Nonnull StagedChunkGenerator.ExecutorTier var4,
      boolean var5
   ) {
      Bounds3i var6 = GridUtils.createChunkBounds_voxelGrid(var1.x(), var1.z());
      Bounds3i var7 = GridUtils.createChunkBounds_bufferGrid(var1.x(), var1.z());
      BufferBundle.Access var8 = this.bufferBundle.createBufferAccess(this.tintOutput_bufferType, var7);
      VoxelSpace var9 = new PixelBufferView<>(var8.createView(), Integer.class);
      GeneratedBlockChunk var10 = var2.getBlockChunk();
      HierarchicalTimingProfiler.Probe var11 = var3.createProbe("Tints");
      class="kw">return CompletableFuture.runAsync(() -> {
         var11.start(var5);
         Vector3i var5 = new Vector3i();
         var5.y = 0;

         for (int var6 = 0; var6 < 32; var6++) {
            for (int var7 = 0; var7 < 32; var7++) {
               var5.x = var6 + var6.min.x;
               var5.z = var7 + var6.min.z;
               Integer var8 = var9.get(var5);
               if (var8 == null) {
                  var10.setTint(var6, var7, 0);
               } else {
                  var10.setTint(var6, var7, var8);
               }
            }
         }

         var11.stop(var5);
      }, var4.executor()).handle((var0, var1x) -> {
         if (var1x == null) {
            class="kw">return null;
         }

         LoggerUtil.logException("a HytaleGenerator async process", var1x, LoggerUtil.getLogger());
         class="kw">return null;
      });
   }

   @Nonnull
   class="kw">private CompletableFuture<Void> transferEnvironments(
      @Nonnull ChunkRequest.Arguments var1,
      @Nonnull GeneratedChunk var2,
      @Nonnull HierarchicalTimingProfiler.Probe var3,
      @Nonnull StagedChunkGenerator.ExecutorTier var4,
      boolean var5
   ) {
      Bounds3i var6 = GridUtils.createChunkBounds_voxelGrid(var1.x(), var1.z());
      Bounds3i var7 = GridUtils.createChunkBounds_bufferGrid(var1.x(), var1.z());
      BufferBundle.Access var8 = this.bufferBundle.createBufferAccess(this.environmentOutput_bufferType, var7);
      VoxelSpace var9 = new VoxelBufferView<>(var8.createView(), Integer.class);
      EnvironmentChunk.BulkWriter var10 = new EnvironmentChunk.BulkWriter();
      int var11 = 0;
      Vector3i var12 = new Vector3i(8, 0, 8);
      Vector3i var13 = new Vector3i(32 / var12.x, 0, 32 / var12.z);
      List var14 = new ArrayList<>();

      for (int var15 = 0; var15 < var13.x; var15++) {
         for (int var16 = 0; var16 < var13.z; var16++) {
            HierarchicalTimingProfiler.Probe var17 = var3.createProbe("Environment Section " + var11++);
            int var18 = var15 * var12.x;
            int var19 = var16 * var12.z;
            int var20 = var18 + var12.x;
            int var21 = var19 + var12.z;
            CompletableFuture var22 = CompletableFuture.runAsync(() -> {
               var17.start(var5);
               Vector3i var9 = new Vector3i();

               for (int var10 = var18; var10 < var20; var10++) {
                  for (int var11 = var19; var11 < var21; var11++) {
                     EnvironmentChunk.BulkWriter.ColumnWriter var12 = var10.getColumnWriter(var10, var11);
                     int var13 = var10;
                     int var14 = var11;
                     var12.intake(var5x -> {
                        var9.x = var13 + var6.min.x;
                        var9.y = var5x + var6.min.y;
                        var9.z = var14 + var6.min.z;
                        Integer var6 = var9.get(var9);
                        assert var6 != null;
                        class="kw">return var6;
                     });
                  }
               }

               var17.stop(var5);
            }, var4.executor());
            var14.add(var22);
         }
      }

      HierarchicalTimingProfiler.Probe var23 = var3.createProbe("Environment Write");
      class="kw">return FutureUtils.allOf(var14).thenRun(() -> {
         var23.start(var5);
         var10.write(var2.getBlockChunk().getEnvironmentChunk());
         var23.stop(var5);
      }).handle((var0, var1x) -> {
         if (var1x == null) {
            class="kw">return null;
         }

         LoggerUtil.logException("a HytaleGenerator async process", var1x, LoggerUtil.getLogger());
         class="kw">return null;
      });
   }

   @Nonnull
   class="kw">private CompletableFuture<Void> transferEntities(
      @Nonnull ChunkRequest.Arguments var1,
      @Nonnull GeneratedChunk var2,
      @Nonnull HierarchicalTimingProfiler.Probe var3,
      @Nonnull StagedChunkGenerator.ExecutorTier var4,
      boolean var5
   ) {
      Bounds3i var6 = GridUtils.createChunkBounds_bufferGrid(var1.x(), var1.z());
      BufferBundle.Access var7 = this.bufferBundle.createBufferAccess(this.entityOutput_bufferType, var6);
      EntityBufferView var8 = new EntityBufferView(var7.createView());
      GeneratedEntityChunk var9 = var2.getEntityChunk();
      HierarchicalTimingProfiler.Probe var10 = var3.createProbe("Entities");
      class="kw">return CompletableFuture.runAsync(
            () -> {
               var10.start(var5);
               var8.forEach(
                  var2x -> var9.addEntities(
                     var2x.getOffset(), var2x.getRotation(), new Holder[]{var2x.getEntityHolder()}, var1.seed(), var2x.getPrefabInstanceId()
                  )
               );
               var10.stop(var5);
            },
            var4.executor()
         )
         .handle((var0, var1x) -> {
            if (var1x == null) {
               class="kw">return null;
            }

            LoggerUtil.logException("a HytaleGenerator async process", var1x, LoggerUtil.getLogger());
            class="kw">return null;
         });
   }

   @Nonnull
   class="kw">private String createBufferRequestCacheReport() {
      StringBuilder var1 = new StringBuilder();
      var1.append("Buffer Cache Report\n");
      var1.append("Total Cache Buffer Requests: ").append(this.totalCacheBufferRequests).append("\n");
      var1.append("Missed Cache Buffer Requests: ").append(this.missedCacheBufferRequests).append("\n");
      double var2 = (double)this.missedCacheBufferRequests / this.totalCacheBufferRequests * 100.0;
      var1.append("Missed/Total Ratio: ").append(var2).append("%\n");
      class="kw">return var1.toString();
   }

   @Nonnull
   class="kw">private String createContextDependencyReport(int var1) {
      StringBuilder var2 = new StringBuilder();
      var2.append("Context Dependency Report\n");

      for (int var3 = 0; var3 < this.stages.length; var3++) {
         Bounds3i var4 = this.stagesOutputBounds_bufferGrid[var3];
         Vector3i var5 = var4.getSize().add(3, 0, 3);
         Vector3d var6 = new Vector3d(var5);
         var6.mul(0.25);
         var2.append("\t".repeat(var1)).append(this.stages[var3].getName()).append(" (Stage ").append(var3).append("):\n");
         var2.append("\t".repeat(var1 + 1)).append("Output Size (Buffer Column): {x=").append(var5.x).append(", z=").append(var5.z).append("}\n");
         var2.append("\t".repeat(var1 + 1)).append("Output Size (Chunk Column): {x=").append(var6.x).append(", z=").append(var6.z).append("}\n");
      }

      class="kw">return var2.toString();
   }

   class="kw">private class="kw">static void setSupport(@Nonnull GeneratedChunk var0, int var1, int var2, int var3, int var4, int var5) {
      Holder[] var6 = var0.getSections();
      Holder var7 = var6[ChunkUtil.chunkCoordinate(var2)];
      if (var5 >= 0) {
         BlockPhysics.setSupportValue(var7, var1, var2, var3, var5);
      } else {
         BlockType var8 = BlockType.getAssetMap().getAsset(var4);
         if (var8 != null && var8.hasSupport()) {
            BlockPhysics.reset(var7, var1, var2, var3);
         } else {
            BlockPhysics.clear(var7, var1, var2, var3);
         }
      }
   }

   class="kw">private class="kw">static void setBoundsToWorldHeight_bufferGrid(@Nonnull Bounds3i var0) {
      var0.min.y = 0;
      var0.max.y = 40;
   }

   class="kw">private class="kw">static boolean isColumnCached(@Nonnull BufferBundle.Access var0, @Nonnull Vector3i var1, int var2) {
      assert var1.y == 0;
      BufferBundle.Tracker var3 = var0.getBuffer(var1).tracker();
      class="kw">return var3.stageIndex == var2;
   }

   class="kw">private class="kw">static void updateTrackersForColumn(int var0, @Nonnull BufferBundle.Access.View var1, @Nonnull Vector3i var2) {
      for (var2.y = 0; var2.y < 40; var2.y++) {
         BufferBundle.Tracker var3 = var1.getBuffer(var2).tracker();
         var3.stageIndex = var0;
      }
   }

   class="kw">public class="kw">static class Builder {
      @Nonnull
      class="kw">public class="kw">final ParametrizedBufferType MATERIAL_OUTPUT_BUFFER_TYPE = new ParametrizedBufferType(
         "MaterialResult", -1, VoxelBuffer.class, Material.class, () -> new VoxelBuffer<>(Material.class)
      );
      @Nonnull
      class="kw">public class="kw">final ParametrizedBufferType TINT_OUTPUT_BUFFER_TYPE = new ParametrizedBufferType(
         "TintResult", -3, SimplePixelBuffer.class, Integer.class, () -> new SimplePixelBuffer<>(Integer.class)
      );
      @Nonnull
      class="kw">public class="kw">final ParametrizedBufferType ENVIRONMENT_OUTPUT_BUFFER_TYPE = new ParametrizedBufferType(
         "EnvironmentResult", -4, VoxelBuffer.class, Integer.class, () -> new VoxelBuffer<>(Integer.class)
      );
      @Nonnull
      class="kw">public class="kw">final BufferType ENTITY_OUTPUT_BUFFER_TYPE = new BufferType("EntityResult", -5, EntityBuffer.class, EntityBuffer::new);
      @Nonnull
      class="kw">private class="kw">final List<Stage> stages = new ArrayList<>();
      @Nullable
      class="kw">private MaterialCache materialCache;
      @Nullable
      class="kw">private String statsHeader;
      @Nullable
      class="kw">private IntSet statsCheckpoints;
      @Nullable
      class="kw">private PositionProvider spawnPositions;
      @Nonnull
      class="kw">private class="kw">final Map<String, StagedChunkGenerator.ExecutorTier> concurrencyTiers = new HashMap<>();
      @Nonnull
      class="kw">private String profiledExecutorKey = "";
      class="kw">private double bufferCapacityFactor;
      class="kw">private double targetViewDistance;
      class="kw">private double targetPlayerCount;

      class="kw">public Builder() {
      }

      @Nonnull
      class="kw">public StagedChunkGenerator build() {
         assert !this.concurrencyTiers.isEmpty();
         assert this.materialCache != null;
         assert this.statsHeader != null;
         assert this.statsCheckpoints != null;
         assert this.spawnPositions != null;
         StagedChunkGenerator var1 = new StagedChunkGenerator();
         var1.materialOutput_bufferType = this.MATERIAL_OUTPUT_BUFFER_TYPE;
         var1.tintOutput_bufferType = this.TINT_OUTPUT_BUFFER_TYPE;
         var1.environmentOutput_bufferType = this.ENVIRONMENT_OUTPUT_BUFFER_TYPE;
         var1.entityOutput_bufferType = this.ENTITY_OUTPUT_BUFFER_TYPE;
         var1.stages = new Stage[this.stages.size()];
         this.stages.toArray(var1.stages);
         Set var2 = this.createListOfAllBufferTypes();
         Int2ObjectMap var3 = this.createStageDependencyMap();
         var1.stagesOutputBounds_bufferGrid = this.createTotalOutputBoundsArray(var3);
         var1.bufferBundle = new BufferBundle();
         var1.bufferBundle
            .createGrid(this.MATERIAL_OUTPUT_BUFFER_TYPE, this.resolveBufferCapacity(this.MATERIAL_OUTPUT_BUFFER_TYPE, var1.stagesOutputBounds_bufferGrid));
         var1.bufferBundle
            .createGrid(this.TINT_OUTPUT_BUFFER_TYPE, this.resolveBufferCapacity(this.TINT_OUTPUT_BUFFER_TYPE, var1.stagesOutputBounds_bufferGrid));
         var1.bufferBundle
            .createGrid(
               this.ENVIRONMENT_OUTPUT_BUFFER_TYPE, this.resolveBufferCapacity(this.ENVIRONMENT_OUTPUT_BUFFER_TYPE, var1.stagesOutputBounds_bufferGrid)
            );
         var1.bufferBundle
            .createGrid(this.ENTITY_OUTPUT_BUFFER_TYPE, this.resolveBufferCapacity(this.ENTITY_OUTPUT_BUFFER_TYPE, var1.stagesOutputBounds_bufferGrid));

         for (BufferType var5 : var2) {
            if (!this.isGeneratorOutputBufferType(var5)) {
               var1.bufferBundle.createGrid(var5, this.resolveBufferCapacity(var5, var1.stagesOutputBounds_bufferGrid));
            }
         }

         var1.executorTiers = new HashMap<>(this.concurrencyTiers);
         var1.profiledExecutorKey = this.profiledExecutorKey;
         var1.materialCache = this.materialCache;
         var1.hierarchicalTimingProfiler = new HierarchicalTimingProfiler(this.statsHeader);
         var1.statsCheckpoints = new IntOpenHashSet(this.statsCheckpoints);
         var1.generatedChunkCount = 0;
         var1.spawnPositions = this.spawnPositions;
         class="kw">return var1;
      }

      @Nonnull
      class="kw">public StagedChunkGenerator.Builder withStats(@Nonnull String var1, @Nonnull IntSet var2) {
         this.statsHeader = var1;
         this.statsCheckpoints = new IntOpenHashSet(var2);
         class="kw">return this;
      }

      @Nonnull
      class="kw">public StagedChunkGenerator.Builder withSpawnPositions(@Nonnull PositionProvider var1) {
         this.spawnPositions = var1;
         class="kw">return this;
      }

      @Nonnull
      class="kw">public StagedChunkGenerator.Builder addExecutorTier(@Nonnull String var1, @Nonnull StagedChunkGenerator.ExecutorTier var2) {
         this.concurrencyTiers.put(var1, var2);
         class="kw">return this;
      }

      @Nonnull
      class="kw">public StagedChunkGenerator.Builder setProfiledExecutorKey(@Nonnull String var1) {
         this.profiledExecutorKey = var1;
         class="kw">return this;
      }

      @Nonnull
      class="kw">public StagedChunkGenerator.Builder withMaterialCache(@Nonnull MaterialCache var1) {
         this.materialCache = var1;
         class="kw">return this;
      }

      @Nonnull
      class="kw">public StagedChunkGenerator.Builder withBufferCapacity(double var1, double var3, double var5) {
         assert var1 >= 0.0;
         assert var3 >= 0.0;
         assert var5 >= 0.0;
         this.bufferCapacityFactor = var1;
         this.targetViewDistance = var3;
         this.targetPlayerCount = var5;
         class="kw">return this;
      }

      @Nonnull
      class="kw">public StagedChunkGenerator.Builder appendStage(@Nonnull Stage var1) {
         this.stages.add(var1);
         class="kw">return this;
      }

      @Nonnull
      class="kw">private IntList createStagesThatReadFrom(int var1) {
         Stage var2 = this.stages.get(var1);
         IntList var3 = new IntArrayList();
         List var4 = var2.getOutputTypes();

         for (int var5 = 0; var5 < var4.size(); var5++) {
            BufferType var6 = var4.get(var5);

            for (int var7 = 0; var7 < this.stages.size(); var7++) {
               Stage var8 = this.stages.get(var7);
               if (var8.getInputTypesAndBounds_bufferGrid().containsKey(var6)) {
                  var3.add(var7);
               }
            }
         }

         class="kw">return var3;
      }

      @Nonnull
      class="kw">private Int2ObjectMap<IntSet> createStageDependencyMap() {
         Int2ObjectMap var1 = new Int2ObjectOpenHashMap();

         for (int var2 = 0; var2 < this.stages.size(); var2++) {
            var1.put(var2, new IntOpenHashSet(1));
         }

         for (int var6 = 0; var6 < this.stages.size(); var6++) {
            IntList var3 = this.createStagesThatReadFrom(var6);
            IntListIterator var4 = var3.iterator();

            while (var4.hasNext()) {
               int var5 = (Integer)var4.next();
               ((IntSet)var1.get(var5)).add(var6);
            }
         }

         class="kw">return var1;
      }

      class="kw">private int resolveBufferCapacity(@Nonnull BufferType var1, @Nonnull Bounds3i[] var2) {
         int var3 = 0;

         while (var3 < var2.length && !this.stages.get(var3).getOutputTypes().contains(var1)) {
            var3++;
         }

         if (var3 >= var2.length) {
            class="kw">return 0;
         }

         Bounds3i var4 = var2[var3];
         class="kw">return calculateCapacityFromBounds(var4, this.bufferCapacityFactor, this.targetViewDistance, this.targetPlayerCount);
      }

      class="kw">private class="kw">static int calculateCapacityFromBounds(@Nonnull Bounds3i var0, double var1, double var3, double var5) {
         assert var1 >= 0.0;
         assert var3 >= 0.0;
         assert var5 >= 0.0;
         Vector3i var7 = var0.getSize();
         if (var7.x == 1 && var7.z == 1) {
            class="kw">return 0;
         }

         double var8 = var3 / VoxelBuffer.SIZE.x;
         double var10 = var7.x + var8 * 2.0;
         var10 *= var7.z + var8 * 2.0;
         double var12;
         if (!(var7.x > var8) && !(var7.z > var8)) {
            var12 = (var8 - var7.x / 2.0) * (var8 - var7.z / 2.0);
         } else {
            var12 = 0.0;
         }

         double var14 = var10 - var12;
         double var16 = var14 * var5;
         double var18 = var16 * var1;
         double var20 = var18 * 40.0;
         assert var20 >= 0.0;
         class="kw">return Math.max(0, (int)var20);
      }

      class="kw">private void createTotalOutputBoundsForStage(int var1, @Nonnull Int2ObjectMap<IntSet> var2, @Nonnull Bounds3i[] var3) {
         Bounds3i var4 = new Bounds3i(Vector3iUtil.ZERO, Vector3iUtil.ALL_ONES);
         Stage var5 = this.stages.get(var1);
         List var6 = new ArrayList<>();

         for (int var7 = this.stages.size() - 1; var7 >= var1 + 1; var7--) {
            if (((IntSet)var2.get(var7)).contains(var1)) {
               Stage var8 = this.stages.get(var7);
               Map var9 = var8.getInputTypesAndBounds_bufferGrid();

               for (BufferType var11 : var5.getOutputTypes()) {
                  Bounds3i var12 = var9.get(var11);
                  if (var12 != null) {
                     Bounds3i var13 = var3[var7];
                     Bounds3i var14 = var13.clone().stack(var12);
                     var6.add(var14);
                  }
               }
            }
         }

         if (var6.isEmpty()) {
            StagedChunkGenerator.setBoundsToWorldHeight_bufferGrid(var4);
            var3[var1] = var4;
         } else {
            Bounds3i var15 = var6.getFirst().clone();

            for (int var16 = 1; var16 < var6.size(); var16++) {
               var15.encompass(var6.get(var16));
            }

            StagedChunkGenerator.setBoundsToWorldHeight_bufferGrid(var15);
            var3[var1] = var15;
         }
      }

      @Nonnull
      class="kw">private Bounds3i[] createTotalOutputBoundsArray(@Nonnull Int2ObjectMap<IntSet> var1) {
         Bounds3i[] var2 = new Bounds3i[this.stages.size()];

         for (int var3 = this.stages.size() - 1; var3 >= 0; var3--) {
            this.createTotalOutputBoundsForStage(var3, var1, var2);
         }

         class="kw">return var2;
      }

      @Nonnull
      class="kw">private Set<BufferType> createListOfAllBufferTypes() {
         Set var1 = new HashSet<>();

         for (int var2 = 0; var2 < this.stages.size(); var2++) {
            Stage var3 = this.stages.get(var2);
            var1.addAll(var3.getInputTypesAndBounds_bufferGrid().keySet());
            var1.addAll(var3.getOutputTypes());
         }

         class="kw">return var1;
      }

      @Nonnull
      class="kw">private class="kw">static Bounds3i getEncompassingBounds(@Nonnull Collection<Bounds3i> var0) {
         Bounds3i var1 = new Bounds3i();

         for (Bounds3i var3 : var0) {
            var1.encompass(var3);
         }

         class="kw">return var1;
      }

      class="kw">private boolean isGeneratorOutputBufferType(@Nonnull BufferType var1) {
         class="kw">return var1.equals(this.MATERIAL_OUTPUT_BUFFER_TYPE)
            || var1.equals(this.TINT_OUTPUT_BUFFER_TYPE)
            || var1.equals(this.ENVIRONMENT_OUTPUT_BUFFER_TYPE)
            || var1.equals(this.ENTITY_OUTPUT_BUFFER_TYPE);
      }
   }

   class="kw">public record ExecutorTier(@Nonnull ExecutorService executor, @Nonnull WorkerIndexer workerIndexer) {
      class="kw">public ExecutorTier {
      }
   }
}