30    public const COORD_BIT_SIZE = 4;
 
   31    public const COORD_MASK = ~(~0 << self::COORD_BIT_SIZE);
 
   32    public const EDGE_LENGTH = 1 << self::COORD_BIT_SIZE;
 
   41        private int $emptyBlockId,
 
   42        private array $blockLayers,
 
   43        private PalettedBlockArray $biomes,
 
   44        private ?LightArray $skyLight = 
null,
 
   45        private ?LightArray $blockLight = 
null 
 
   54        $this->collectGarbage();
 
 
   63        return count($this->blockLayers) === 0;
 
 
   72    public function getBlockStateId(
int $x, 
int $y, 
int $z) : int{
 
   73        if(count($this->blockLayers) === 0){
 
   74            return $this->emptyBlockId;
 
   76        return $this->blockLayers[0]->get($x, $y, $z);
 
   79    public function setBlockStateId(
int $x, 
int $y, 
int $z, 
int $block) : void{
 
   80        if(count($this->blockLayers) === 0){
 
   81            $this->blockLayers[] = 
new PalettedBlockArray($this->emptyBlockId);
 
   83        $this->blockLayers[0]->set($x, $y, $z, $block);
 
   91        return $this->blockLayers;
 
 
   94    public function getHighestBlockAt(
int $x, 
int $z) : ?int{
 
   95        if(count($this->blockLayers) === 0){
 
   98        for($y = self::EDGE_LENGTH - 1; $y >= 0; --$y){
 
   99            if($this->blockLayers[0]->
get($x, $y, $z) !== $this->emptyBlockId){
 
  107    public function getBiomeArray() : PalettedBlockArray{ return $this->biomes; }
 
  109    public function getBlockSkyLightArray() : LightArray{
 
  110        return $this->skyLight ??= LightArray::fill(0);
 
  113    public function setBlockSkyLightArray(LightArray $data) : void{
 
  114        $this->skyLight = $data;
 
  117    public function getBlockLightArray() : LightArray{
 
  118        return $this->blockLight ??= LightArray::fill(0);
 
  121    public function setBlockLightArray(LightArray $data) : void{
 
  122        $this->blockLight = $data;
 
  132    public function collectGarbage() : void{
 
  134        foreach($this->blockLayers as $layer){
 
  135            $layer->collectGarbage();
 
  137            if($layer->getBitsPerBlock() !== 0 || $layer->get(0, 0, 0) !== $this->emptyBlockId){
 
  138                $cleanedLayers[] = $layer;
 
  141        $this->blockLayers = $cleanedLayers;
 
  142        $this->biomes->collectGarbage();
 
  144        if($this->skyLight !== 
null && $this->skyLight->isUniform(0)){
 
  145            $this->skyLight = 
null;
 
  147        if($this->blockLight !== 
null && $this->blockLight->isUniform(0)){
 
  148            $this->blockLight = 
null;
 
  152    public function __clone(){
 
  153        $this->blockLayers = array_map(
function(PalettedBlockArray $array) : PalettedBlockArray{
 
  155        }, $this->blockLayers);
 
  156        $this->biomes = clone $this->biomes;
 
  158        if($this->skyLight !== 
null){
 
  159            $this->skyLight = clone $this->skyLight;
 
  161        if($this->blockLight !== 
null){
 
  162            $this->blockLight = clone $this->blockLight;