Слой биома

Версия Minecraft
1.12.2
5,018
47
783
Суть проблемы в следующем. Согласно моей задумке, в биомпровайдере биомослои накладываются друг на друга.
Сперва генерируется 3 биома каждого типа первым слоем биомов(для различия назову их регионами - магматический, метаморфический и осадочный).
Затем должно генерироваться еще по 4 подтипа каждого из этих регионов с помощью трех новых слоев с биомами, отталкиваясь от проверки на точке на биом.(Это нужно, чтобы биомы одного региона находились по возможности рядом с друг другом для реалистичности)

Java:
    public GenLayer[] getModdedBiomeGenerators(WorldType worldType, long seed, GenLayer[] original)
    {
      
        GenLayer start = new RealGenLayerIsland(1L);
         start = new GenLayerFuzzyZoom(2000L, start);
         start = new GenLayerZoom(21000L, start);
         GenLayer layer1 = new GenLayerAddIsland(1L, start);
         layer1 = new GenLayerAddIsland(50L, layer1);
         layer1 = new GenLayerAddIsland(70L, layer1);
         GenLayer layerzoom1 = new GenLayerZoom(1001L, layer1);
         layerzoom1 = new GenLayerZoom(1001L, layerzoom1);
         layerzoom1 = new GenLayerZoom(1002L, layerzoom1);
         layerzoom1 = new GenLayerZoom(1003L, layerzoom1);
         layerzoom1 = new GenLayerZoom(1004L, layerzoom1);
         layerzoom1 = new GenLayerZoom(1005L, layerzoom1);
         layerzoom1 = new GenLayerZoom(1006L, layerzoom1);
         GenLayer layer2 = GenLayerZoom.magnify(1000L, layerzoom1, 0);
        GenLayer biomes  = new GenLayerBiomes(1L);
        GenLayer subbiomes1  = new GenLayerMetamorphicBiomes(1L);

        biomes = new GenLayerFuzzyZoom(2000L, biomes);
    biomes = new GenLayerZoom(1001L, biomes);
        biomes = new GenLayerZoom(1002L, biomes);
        biomes = new GenLayerZoom(1003L, biomes);
        biomes = new GenLayerZoom(1004L, biomes);
        biomes = new GenLayerZoom(1005L, biomes);
        biomes = new GenLayerZoom(1006L, biomes);

   
         
         GenLayer biomeIndexLayer = new GenLayerVoronoiZoom(10L, biomes);
       

         start.initWorldGenSeed(seed);
    drawImage(1000, biomes, "biomes");
    drawImage(1000, subbiomes1, "subbiomes1");

            return new GenLayer[]{
                    layer2, biomes, subbiomes1,
                    biomeIndexLayer
            };

    }
}

Пошел с самого начала. Сперва, исходя из логики, подумал что раз это уже биомы одного региона, то они должны получить массив родительского слоя, то есть тех трех изначальных регионов.
Написал так:
Java:
public class GenLayerMagmaticBiomes  extends GenLayer {
   

    private int magmatic_hills = Biome.getIdForBiome(RegBiomes.MAGMATIC_HILLS);
    private int magmatic_desert = Biome.getIdForBiome(RegBiomes.MAGMATIC_DESERT);
    private int magmatic_lake = Biome.getIdForBiome(RegBiomes.MAGMATIC_LAKE);
    private int magmatic_swamp = Biome.getIdForBiome(RegBiomes.MAGMATIC_SWAMP);

    public final int[] all_biomes = { magmatic_hills,magmatic_desert,magmatic_lake,magmatic_swamp};
   
    public GenLayerMagmaticBiomes(long seed, GenLayer parent) {
        super(seed);
        this.parent = parent;

    }
   

     public int[] getInts(int areaX, int areaY, int areaWidth, int areaHeight)
        {
            int[] aint = this.parent.getInts(areaX, areaY, areaWidth, areaHeight);
            int[] aint1 = IntCache.getIntCache(areaWidth * areaHeight);

            for (int i = 0; i < areaHeight; ++i)
            {
                for (int j = 0; j < areaWidth; ++j)
                {
                    this.initChunkSeed((long)(j + areaX), (long)(i + areaY));
                    int k = aint[j + i * areaWidth];
                    int l = (k & 3840) >> 8;
                    k = k & -3841;
                     if (isBiomeOceanic(k))
                    {
                        aint1[j + i * areaWidth] = k;
                    }
                     else
                    if (k == Biome.getIdForBiome(RegBiomes.MAGMATIC_PLAINS))
                    {
                        aint1[j + i * areaWidth] =  this.all_biomes[nextInt(this.all_biomes.length)];
                    }
             
                }
            }

            return aint1;
        }

}

Оно не сработало. Как было три основных биома, так и осталось. Что то сделал не так?
Затем попробовал сделать без родительского слоя. Что тоже не работает.
Затем решил что чем перестать тыркатся впустую и тратить время, спросить совета у тех, кто лучше меня разбирается в слоях, в чем тут дело и как бы это исправить.
Java:
public class GenLayerMetamorphicBiomes  extends GenLayer {


    private int metamorphic_hills = Biome.getIdForBiome(RegBiomes.METAMORPHIC_HILLS);
    private int metamorphic_desert = Biome.getIdForBiome(RegBiomes.METAMORPHIC_DESERT);
    private int metamorphic_lake = Biome.getIdForBiome(RegBiomes.METAMORPHIC_LAKE);
    private int metamorphic_swamp = Biome.getIdForBiome(RegBiomes.METAMORPHIC_SWAMP);

    public final int[] all_biomes = { metamorphic_hills,metamorphic_desert,metamorphic_lake,metamorphic_swamp};

    public GenLayerMetamorphicBiomes(long seed) {
        super(seed);

    }


    public int[] getInts(int x, int z, int width, int height)
    {
        int[] dest = IntCache.getIntCache(width * height);

        for (int dz = 0; dz < height; dz++) {
            for (int dx = 0; dx < width; dx++) {
                int k = dest[dz + dx * width];
                int l = (k & 3840) >> 8;
            k = k & -3841;

            if (k == Biome.getIdForBiome(RegBiomes.METAMORPHIC_PLAINS))
            {
                initChunkSeed(dx + x, dz + z);
                dest[(dx + dz * width)] = this.all_biomes[nextInt(this.all_biomes.length)];
            }
            }
        }

        return dest;
    }

}
 
Решение
Ты в своем алгоритме не используешь RealGenLayerIsland.

Код, который ты закомментил в RealGenLayerIsland, возник из-за специфики генератор для ванилы: генерирует землю рядом с нулевыми координатами, ну или прямо на них. Строка актуальна для генерации чанков в радиусе до 4000-5000 чанков, считая от нуля (что-то в этом духе). Равнина генерируется потому, что ее идентификатор - 1. Ванила впоследствии заменяет единицу, которая изначально означет "не море", на биомы, а ты этого не делаешь, т.к. генеришь сразу биомы вначале.

Зачем два раза вызываешь initWorldGenSeed? Так не надо делать.

И опять не используешь родителя в GenLayerBiomes. Зачем тогда писать весь код до вызова этого слоя? Сейчас твой код в действительности выглядит так:
Java:
...
5,018
47
783
Переделал немного, сделал так, чтобы 3 основных региона спавнились в самом начале - то есть в стоковом GenLayerIsland. Далее, хотел накладывать биомы, но они как то криво втыкаются, будто бы с глюками. В чем тут дело? Особо бы хотел услышать мнение @yoloven :)
Причем замечено, что больше одного слоя с биомами наложить не удается. Если накладываю второй поверх первых трех, остаются только верхние.
UPD. Проблема в том, что мне требуется генерировать разные биомы друг с другом рядом, а не рандомно. Рандомно - могу засунуть в массив и все четко.
Java:
    public GenLayer[] getModdedBiomeGenerators(WorldType worldType, long seed, GenLayer[] original)
    {

        GenLayer start = new RealGenLayerIsland(1L);
         start = new GenLayerFuzzyZoom(2000L, start);
         start = new GenLayerZoom(2000L, start);
         GenLayer layer1 = new GenLayerAddIsland(1L, start);
         layer1 = new GenLayerAddIsland(50L, layer1);
         layer1 = new GenLayerAddIsland(70L, layer1);
         GenLayer layerzoom1 = new GenLayerZoom(1001L, layer1);
         layerzoom1 = new GenLayerZoom(1001L, layerzoom1);
         layerzoom1 = new GenLayerZoom(1002L, layerzoom1);
         layerzoom1 = new GenLayerZoom(1003L, layerzoom1);
         layerzoom1 = new GenLayerZoom(1004L, layerzoom1);
         layerzoom1 = new GenLayerSmooth(1001L, layerzoom1);
    //     layerzoom1 = new GenLayerSmooth(1002L, layerzoom1);
    //     layerzoom1 = new GenLayerZoom(1005L, layerzoom1);
         GenLayer biomes = new GenLayerSubBiomes(seed);
         biomes = new GenLayerZoom(1002L, biomes);
         biomes = new GenLayerZoom(1003L, biomes);
         biomes = new GenLayerZoom(1004L, biomes);
         biomes = new GenLayerZoom(1005L, biomes);
         biomes = new GenLayerZoom(1006L, biomes);
         biomes = new GenLayerSmooth(1004L, biomes);
         biomes = new GenLayerSmooth(1004L, biomes);
         biomes = new GenLayerSmooth(1004L, biomes);
         GenLayer biomeIndexLayer = new GenLayerVoronoiZoom(10L, biomes);
      

         start.initWorldGenSeed(seed);
//    drawImage(1000, biomeIndexLayer, "biomeIndexLayer");
//    drawImage(1000, biomes, "biomes");

            return new GenLayer[]{
                    biomes,
                    biomeIndexLayer
            };

    }
}
2020-04-17_20.46.03.png
 
Последнее редактирование:
102
3
77
В ванильном майне реализованы такие "регионы": DESERT, WARM, COOL, ICY. Сначала они генерируются, а затем дробятся на настоящие биомы. У тебя аналогичный случай.

Разберем первый код:
Суть проблемы в следующем. Согласно моей задумке, в биомпровайдере биомослои накладываются друг на друга.
Сперва генерируется 3 биома каждого типа первым слоем биомов(для различия назову их регионами - магматический, метаморфический и осадочный).
Затем должно генерироваться еще по 4 подтипа каждого из этих регионов с помощью трех новых слоев с биомами, отталкиваясь от проверки на точке на биом.(Это нужно, чтобы биомы одного региона находились по возможности рядом с друг другом для реалистичности)
код

Код RealGenLayerIsland не показал, наверное там новых биомов нет.
GenLayer start = new RealGenLayerIsland(1L);

На версии 1.12.2 такого слоя нет, значит это тоже твой слой, код которого ты не скинул.
GenLayer biomes = new GenLayerBiomes(1L);

Этого тоже нет.
GenLayer subbiomes1 = new GenLayerMetamorphicBiomes(1L);

А вообще, по сути все эти слои выше были бессмысленны, потому что в итоге ты их не используешь. layer2 и subbiomes1 нигде не используются при генерации твоего конечного biomes. По факту ты только его и используешь. Плюс ко всем, в конце у тебя start.initWorldGenSeed(seed);, хотя вроде как ты использовал именно biomes для генерации.


После этого ты кидаешь код слоя GenLayerMagmaticBiomes, которого нет в коде генерации твоих биомов.
Опять же, где ты до этого в родителе создаешь этот биом, я не знаю. Но если все-таки создаешь, значит будет работать.
if (k == Biome.getIdForBiome(RegBiomes.MAGMATIC_PLAINS))
Что касается того, что ты потом сделал все без родителя - Тогда этот слой должен быть первым, который ты потом будешь масштабировать.

Что там стало с последним кодом уже нет смысла смотреть, скорее всего там такие же ошибки. Разберись со слоями, у кого какой родитель. По поводу скриншота - GenLayerVoronoiZoom масштабирует слой так, что ты не сможешь получить биомы с такими прямыми сторонами (ну или придется постараться, что такое найти). Скорее всего ты сфоткал опять же неправильную генерацию.

UPD: Надо смореть не на скрин, а на отладку, где указывается биом, в котором ты находишься. GenLayzerVoronoiZoom вообще не влият по сути на твою генерацию. Он всего лишь растягивает массив до 16x16 чтобы потом отображать его, например, на карте или в той же отладке. Сам мир генерится из массива 11x11 (не помню). То есть у тяб ошибка в процессе генерирования слоев.
 
Последнее редактирование:
5,018
47
783
Со времен последнего ответа я уже неплохо помучался и продвинулся в изученьи)
Воообщем. Решил начать все сначала, перечитал твой тутор и взял за основу твой АГО из тутора, с одной лишь заменой стартового GenLayerIsland на свой(код прилагаю, извиняюсь что забыл)

Пробовал сейчас два варианта генерить. Первый - взять как основной GenLayerIsland обычный ванильный, на который потом накладывается слой с регионами(, а потом накладывается слой с суббиомами, который уже их подразделяет. Второе - я создаю три родительских региона прямо в своем RealGenLayerIsland, которые затем по всякому крутятся-вертятся в соответствии с АГО и к ним применяется слой суббиомов. Итог, в конце ответа в картинках.

Java:
public class RealGenLayerIsland extends GenLayer
{
    public RealGenLayerIsland(long p_i2124_1_)
    {
        super(p_i2124_1_);
    }
    private int de_oc = Biome.getIdForBiome(RegBiomes.DEEP_OCEAN);

    private int sed = Biome.getIdForBiome(RegBiomes.SEDIMENTARY_PLAINS);
    private int mgm = Biome.getIdForBiome(RegBiomes.MAGMATIC_PLAINS);
    private int mtm = Biome.getIdForBiome(RegBiomes.METAMORPHIC_PLAINS);

    public int[] getInts(int areaX, int areaY, int areaWidth, int areaHeight)
    {
        int[] aint = IntCache.getIntCache(areaWidth * areaHeight);

        for (int i = 0; i < areaHeight; ++i)
        {
            for (int j = 0; j < areaWidth; ++j)
            {
                int idCache = aint[j + i * areaWidth];
                this.initChunkSeed((long)(areaX + j), (long)(areaY + i));
                int chance = this.nextInt(2);
                if(chance == 0) {
                     aint[j + i * areaWidth] = this.nextInt(10) == 0 ? sed : de_oc;
                } else
                if(chance == 1) {
                    aint[j + i * areaWidth] = this.nextInt(10) == 0 ? mgm : de_oc;
               }
                else
                    if(chance == 2) {
                        aint[j + i * areaWidth] = this.nextInt(10) == 0 ? mtm : de_oc;
                   }
                }
       
       
        }
//вообще не понял что это за условие и что оно проверяет, поэтому на всякий случай удалил, так как из-за него постоянно вылезал //ванильный plains
        if (areaX > -areaWidth && areaX <= 0 && areaY > -areaHeight && areaY <= 0)
        {

        //     aint[-areaX + -areaY * areaWidth] = 1;
   
        }

        return aint;
    }
}
Java:
public class GenLayerBiomes extends GenLayer{


    private int metamorphic_plains = Biome.getIdForBiome(RegBiomes.METAMORPHIC_PLAINS);
    private int magmatic_plains = Biome.getIdForBiome(RegBiomes.MAGMATIC_PLAINS);
    private int sedimentary_plains = Biome.getIdForBiome(RegBiomes.SEDIMENTARY_PLAINS);



    public final int[] all_biomes = { metamorphic_plains, magmatic_plains, sedimentary_plains};

    public GenLayerBiomes(long seed) {
        super(seed);


    }
    @Override
    public int[] getInts(int x, int z, int width, int height) {
        int[] dest = IntCache.getIntCache(width * height);
        int ndx;
        int ndz;
        for (int dz = 0; dz < height; dz++) {
            for (int dx = 0; dx < width; dx++) {
                initChunkSeed(dx + x, dz + z);
                 int k = dest[(dx + dz * width)];//Получение id биома
                     dest[(dx + dz * width)] = this.all_biomes[nextInt(this.all_biomes.length)];
                //     System.out.println("(dx + dz * width) " +(dx + dz * width));
            }
        }

        return dest;
    }
}
public class GenLayerSubBiomes extends GenLayer {

private int sedimentary_knoll = Biome.getIdForBiome(RegBiomes.SEDIMENTARY_KNOLL);
private int sedimentary_desert = Biome.getIdForBiome(RegBiomes.SEDIMENTARY_DESERT);
private int sedimentary_swamp = Biome.getIdForBiome(RegBiomes.SEDIMENTARY_SWAMP);
private int sedimentary_plains = Biome.getIdForBiome(RegBiomes.SEDIMENTARY_PLAINS);
public final int[] sedimentary_biomes = { sedimentary_plains, sedimentary_knoll,sedimentary_desert,sedimentary_swamp};
public GenLayerSubBiomes(long seed, GenLayer parent) {
super(seed);
this.parent = parent;
}
@Override
public int[] getInts(int x, int z, int width, int height) {
int[] aint = this.parent.getInts(x, z, width, height);
int[] dest = IntCache.getIntCache(width * height);

for (int dz = 0; dz < height; dz++) {
for (int dx = 0; dx < width; dx++) {
initChunkSeed(dx + x, dz + z);
int k = aint[(dx + dz * width)];//Получение id биома
if(k == Biome.getIdForBiome(RegBiomes.SEDIMENTARY_PLAINS)) {
dest[(dx + dz * width)] = this.sedimentary_biomes[nextInt(this.sedimentary_biomes.length)];

}
}
}
return dest;
}
}

Первый вариант - получилась какая то кривая каша. Хотя похоже на правду, но думаю это вообще неправильно. Но истина где то рядом
2020-04-17_23.19.51.png
Java:
public GenLayer[] getModdedBiomeGenerators(WorldType worldType, long seed, GenLayer[] original)
    {
        GenLayer genlayer = new GenLayerIsland(1L);
        genlayer = new GenLayerFuzzyZoom(2000L, genlayer);
        genlayer = new GenLayerAddIsland(1L, genlayer);
        genlayer = new GenLayerZoom(2001L, genlayer);
        genlayer = new GenLayerAddIsland(2L, genlayer);
        genlayer = new GenLayerAddIsland(50L, genlayer);
        genlayer = new GenLayerAddIsland(70L, genlayer);
        genlayer = new GenLayerRemoveTooMuchOcean(2L, genlayer);
        genlayer = new GenLayerAddIsland(3L, genlayer);
        genlayer = new GenLayerZoom(2002L, genlayer);
        genlayer = new GenLayerZoom(2003L, genlayer);
        GenLayer pre_river = new GenLayerAddIsland(4L, genlayer);
        genlayer = GenLayerZoom.magnify(1000L, pre_river, 2);
        int biomeSize = 4;

        for (int k = 0; k < biomeSize; k++) {
            genlayer = new GenLayerZoom((long) (1000 + k), genlayer);

            if (k == 0) {
                genlayer = new GenLayerAddIsland(3L, genlayer);
            }
        }

    genlayer = new GenLayerBiomes(seed);
        genlayer = new GenLayerSubBiomes(seed, genlayer);

        GenLayer genlayer_world = new GenLayerSmooth(1000L, genlayer);
        genlayer = new GenLayerVoronoiZoom(10L, genlayer_world);
        genlayer_world.initWorldGenSeed(seed);
        genlayer.initWorldGenSeed(seed);
        return new GenLayer[] { genlayer_world, genlayer, genlayer_world };
    }

Второй вариант - все гораздо хуже

2020-04-17_23.28.37.png
Java:
    public GenLayer[] getModdedBiomeGenerators(WorldType worldType, long seed, GenLayer[] original)
    {
        GenLayer genlayer = new RealGenLayerIsland(1L);
        genlayer = new GenLayerFuzzyZoom(2000L, genlayer);
        genlayer = new GenLayerAddIsland(1L, genlayer);
        genlayer = new GenLayerZoom(2001L, genlayer);
        genlayer = new GenLayerAddIsland(2L, genlayer);
        genlayer = new GenLayerAddIsland(50L, genlayer);
        genlayer = new GenLayerAddIsland(70L, genlayer);
        genlayer = new GenLayerRemoveTooMuchOcean(2L, genlayer);
        genlayer = new GenLayerAddIsland(3L, genlayer);
        genlayer = new GenLayerZoom(2002L, genlayer);
        genlayer = new GenLayerZoom(2003L, genlayer);
        GenLayer pre_river = new GenLayerAddIsland(4L, genlayer);
        genlayer = GenLayerZoom.magnify(1000L, pre_river, 2);
        int biomeSize = 4;

        for (int k = 0; k < biomeSize; k++) {
            genlayer = new GenLayerZoom((long) (1000 + k), genlayer);

            if (k == 0) {
                genlayer = new GenLayerAddIsland(3L, genlayer);
            }
        }
       // genlayer = new GenLayerBiomes(seed);
        genlayer = new GenLayerSubBiomes(seed, genlayer);
   
        genlayer = new GenLayerZoom(2002L, genlayer);
        genlayer = new GenLayerZoom(2003L, genlayer);
        genlayer = new GenLayerZoom(2004L, genlayer);
        genlayer = new GenLayerZoom(2005L, genlayer);
        GenLayer genlayer_world = new GenLayerSmooth(1000L, genlayer);
        genlayer = new GenLayerVoronoiZoom(10L, genlayer_world);
        genlayer_world.initWorldGenSeed(seed);
        genlayer.initWorldGenSeed(seed);
        return new GenLayer[] { genlayer_world, genlayer, genlayer_world };
    }
 
102
3
77
Ты в своем алгоритме не используешь RealGenLayerIsland.

Код, который ты закомментил в RealGenLayerIsland, возник из-за специфики генератор для ванилы: генерирует землю рядом с нулевыми координатами, ну или прямо на них. Строка актуальна для генерации чанков в радиусе до 4000-5000 чанков, считая от нуля (что-то в этом духе). Равнина генерируется потому, что ее идентификатор - 1. Ванила впоследствии заменяет единицу, которая изначально означет "не море", на биомы, а ты этого не делаешь, т.к. генеришь сразу биомы вначале.

Зачем два раза вызываешь initWorldGenSeed? Так не надо делать.

И опять не используешь родителя в GenLayerBiomes. Зачем тогда писать весь код до вызова этого слоя? Сейчас твой код в действительности выглядит так:
Java:
        GenLayer genlayer = new GenLayerBiomes(seed);
        //genlayer = new GenLayerSubBiomes(seed, genlayer);

        genlayer = new GenLayerSmooth(1000L, genlayer);
        genlayer = new GenLayerVoronoiZoom(10L, genlayer);
        genlayer.initWorldGenSeed(seed);
        return genlayer;

И в следующий раз кидай сид и координаты чанков.
 
5,018
47
783
И опять не используешь родителя в GenLayerBiomes. Зачем тогда писать весь код до вызова этого слоя? Сейчас твой код в действительности выглядит так:
Исправил, сори.
Зачем два раза вызываешь initWorldGenSeed? Так не надо делать.
В твоем туторе так. Можешь сам посмотреть :)
Исправил, удалил.

Так,ну вот с использованием родителя.

Первая картинка - ванильный GenLayerIsland, на который спустя время накладываются мои биомы(GenLayerBiomes + GenLayerSubBiomes). Результат меня не очень радует,честно говоря. Опять сплошь дефолтная трава. Видно, что GenLayerBiomes по какой то причине вообще ничего не нарисовал, а только лишь второй - GenLayerSubBiomes(это про то, что только один слой с биомами почему то нормально рисуется) Сид -8488537456388196246
Java:
public GenLayer[] getModdedBiomeGenerators(WorldType worldType, long seed, GenLayer[] original)
    {
        GenLayer genlayer = new GenLayerIsland(1L);
        genlayer = new GenLayerFuzzyZoom(2000L, genlayer);
        genlayer = new GenLayerAddIsland(1L, genlayer);
        genlayer = new GenLayerZoom(2001L, genlayer);
        genlayer = new GenLayerAddIsland(2L, genlayer);
        genlayer = new GenLayerAddIsland(50L, genlayer);
        genlayer = new GenLayerAddIsland(70L, genlayer);
        genlayer = new GenLayerRemoveTooMuchOcean(2L, genlayer);
        genlayer = new GenLayerAddIsland(3L, genlayer);
        genlayer = new GenLayerZoom(2002L, genlayer);
        genlayer = new GenLayerZoom(2003L, genlayer);
        GenLayer pre_river = new GenLayerAddIsland(4L, genlayer);
        genlayer = GenLayerZoom.magnify(1000L, pre_river, 2);
        int biomeSize = 4;

        for (int k = 0; k < biomeSize; k++) {
            genlayer = new GenLayerZoom((long) (1000 + k), genlayer);

            if (k == 0) {
                genlayer = new GenLayerAddIsland(3L, genlayer);
            }
        }
        genlayer = new GenLayerBiomes(seed, genlayer);
        genlayer = new GenLayerSubBiomes(seed, genlayer);
        
        genlayer = new GenLayerZoom(2002L, genlayer);
        genlayer = new GenLayerZoom(2003L, genlayer);
        genlayer = new GenLayerZoom(2004L, genlayer);
        genlayer = new GenLayerZoom(2005L, genlayer);
        GenLayer genlayer_world = new GenLayerSmooth(1000L, genlayer);
        genlayer = new GenLayerVoronoiZoom(10L, genlayer_world);
      
        drawImage(600, genlayer_world, "genlayer_world2");
        drawImage(600, genlayer, "genlayer2");
        genlayer.initWorldGenSeed(seed);
        System.out.println("seed " + seed);
        return new GenLayer[] { genlayer_world, genlayer, genlayer_world };
    }
2020-04-18_00.51.07.png

Вторая картинка - с использованием в качестве основы моего RealGenLayerIsland, где делаются стоковые регионы.(соответсвенно, GenLayerBiomes уже не учавствует по какой то причине).
Казалось бы все хорошо, но на самом деле нет. Я полетал - абсолютно исчезли другие два региона(магматический и метаморфический), а также если присмотрется, можно увидеть острые грани.
Java:
public GenLayer[] getModdedBiomeGenerators(WorldType worldType, long seed, GenLayer[] original)
    {
        GenLayer genlayer = new RealGenLayerIsland(1L);
        genlayer = new GenLayerFuzzyZoom(2000L, genlayer);
        genlayer = new GenLayerAddIsland(1L, genlayer);
        genlayer = new GenLayerZoom(2001L, genlayer);
        genlayer = new GenLayerAddIsland(2L, genlayer);
        genlayer = new GenLayerAddIsland(50L, genlayer);
        genlayer = new GenLayerAddIsland(70L, genlayer);
        genlayer = new GenLayerRemoveTooMuchOcean(2L, genlayer);
        genlayer = new GenLayerAddIsland(3L, genlayer);
        genlayer = new GenLayerZoom(2002L, genlayer);
        genlayer = new GenLayerZoom(2003L, genlayer);
        GenLayer pre_river = new GenLayerAddIsland(4L, genlayer);
        genlayer = GenLayerZoom.magnify(1000L, pre_river, 2);
        int biomeSize = 4;

        for (int k = 0; k < biomeSize; k++) {
            genlayer = new GenLayerZoom((long) (1000 + k), genlayer);

            if (k == 0) {
                genlayer = new GenLayerAddIsland(3L, genlayer);
            }
        }
     //   genlayer = new GenLayerBiomes(seed, genlayer);
        genlayer = new GenLayerSubBiomes(seed, genlayer);
        
        genlayer = new GenLayerZoom(2002L, genlayer);
        genlayer = new GenLayerZoom(2003L, genlayer);
        genlayer = new GenLayerZoom(2004L, genlayer);
        genlayer = new GenLayerZoom(2005L, genlayer);
        GenLayer genlayer_world = new GenLayerSmooth(1000L, genlayer);
        genlayer = new GenLayerVoronoiZoom(10L, genlayer_world);
      
        drawImage(600, genlayer_world, "genlayer_world2");
        drawImage(600, genlayer, "genlayer2");
        genlayer.initWorldGenSeed(seed);
        System.out.println("seed " + seed);
        return new GenLayer[] { genlayer_world, genlayer, genlayer_world };
    }
Сид -39172169083957444932020-04-18_00.59.48.png

P.S Насчет координат чанков чет не очень понял - их же много? :unsure:
 
102
3
77
По поводу initWorldGenSeed согласен. Я в симуляторе не использую массив, поэтому и не понял зачем два раза писать.

Теперь ты используешь родителя, но новый код ты не скинул.

Лучше использовать вариант, где ты генерирушь регионы в начале, а разделение на биомы - в середине. Это так, как делает это маинкрафт и тогда ты получишь свои суббиомы в регионах.

У тебя по факту должно быть всего 2 новых слоя сейчас: аналоги GenLayerIsland и GenLayerBiome, хотя маинкрафт все равно генерирует регионы не в GenLayerIsland, а позже. В GenLayerIsland появляется только понятие разделения на поверхность и море. Это лишь зависит от того, насолько большими будут твои регионы.

Приложил сид - Приложи координаты чанка
1587184819005.png
 
5,018
47
783
Лучше использовать вариант, где ты генерирушь регионы в начале, а разделение на биомы - в середине. Это так, как делает это маинкрафт и тогда ты получишь свои суббиомы в регионах.
Хорошо, вот.
RealGenLayerIsland выглядит сейчас так. Несмотря на то что код полностью идентичен ванили, острова(материки) не спавнятся по какой то причине вообще. То есть практически всегда вылетает de_oc. Только если поставить nextInt(1) или nextInt(2), появляется шанс встретить землю.
Java:
public class RealGenLayerIsland extends GenLayer
{
    public RealGenLayerIsland(long p_i2124_1_)
    {
        super(p_i2124_1_);
    }
    private int de_oc = Biome.getIdForBiome(RegBiomes.DEEP_OCEAN);
    
    private int sed = Biome.getIdForBiome(RegBiomes.SEDIMENTARY_PLAINS);
    private int mgm = Biome.getIdForBiome(RegBiomes.MAGMATIC_PLAINS);
    private int mtm = Biome.getIdForBiome(RegBiomes.METAMORPHIC_PLAINS);
    
    public int[] getInts(int areaX, int areaY, int areaWidth, int areaHeight)
    {
        int[] aint = IntCache.getIntCache(areaWidth * areaHeight);

        for (int i = 0; i < areaHeight; ++i)
        {
            for (int j = 0; j < areaWidth; ++j)
            {
                int idCache = aint[j + i * areaWidth];
                this.initChunkSeed((long)(areaX + j), (long)(areaY + i));
                int chance = this.nextInt(2);
                if(chance == 0) {

//вообще так c 10 но для того чтобы увидеть сушу снижаю рандомность
//                     aint[j + i * areaWidth] = this.nextInt(10) == 0 ? sed : de_oc;     
aint[j + i * areaWidth] = this.nextInt(1) == 0 ? sed : de_oc;    
                } else
                if(chance == 1) {
                    aint[j + i * areaWidth] = this.nextInt(1) == 0 ? mgm : de_oc;     
               }
                else
                    if(chance == 2) {
                        aint[j + i * areaWidth] = this.nextInt(1) == 0 ? mtm : de_oc;     
                   }
                }
            
            
        }

        if (areaX > -areaWidth && areaX <= 0 && areaY > -areaHeight && areaY <= 0)
        {

        //     aint[-areaX + -areaY * areaWidth] = 1;
        
        }

        return aint;
    }
}
В итоге получается вот так. RealGenLayerIsland + GenLayerBiomes Не совсем плохо, я бы сказал, но по какой то причине резко вставляющиеся чанки, куски незамененной земли, по прежнему остаются.
Java:
public class GenLayerBiomes extends GenLayer{


    private int metamorphic_plains = Biome.getIdForBiome(RegBiomes.METAMORPHIC_PLAINS);
    private int magmatic_plains = Biome.getIdForBiome(RegBiomes.MAGMATIC_PLAINS);
    private int sedimentary_plains = Biome.getIdForBiome(RegBiomes.SEDIMENTARY_PLAINS);

    private int sedimentary_knoll = Biome.getIdForBiome(RegBiomes.SEDIMENTARY_KNOLL);
    private int sedimentary_desert = Biome.getIdForBiome(RegBiomes.SEDIMENTARY_DESERT);
    private int sedimentary_swamp = Biome.getIdForBiome(RegBiomes.SEDIMENTARY_SWAMP);




    private int metamorphic_hills = Biome.getIdForBiome(RegBiomes.METAMORPHIC_HILLS);
    private int metamorphic_desert = Biome.getIdForBiome(RegBiomes.METAMORPHIC_DESERT);
    private int metamorphic_swamp = Biome.getIdForBiome(RegBiomes.METAMORPHIC_SWAMP);

    private int magmatic_hills = Biome.getIdForBiome(RegBiomes.MAGMATIC_HILLS);
    private int magmatic_desert = Biome.getIdForBiome(RegBiomes.MAGMATIC_DESERT);
    private int magmatic_swamp = Biome.getIdForBiome(RegBiomes.MAGMATIC_SWAMP);

    public final int[] sed_biomes = { sedimentary_knoll, sedimentary_swamp, sedimentary_plains, sedimentary_desert};
    public final int[] mtm_biomes = { metamorphic_plains, metamorphic_hills, metamorphic_desert, metamorphic_swamp};
    public final int[] mgm_biomes = { magmatic_hills, magmatic_plains, magmatic_swamp,magmatic_desert};

    public GenLayerBiomes(long seed, GenLayer parent) {
        super(seed);
        this.parent = parent;

    }



    @Override
    public int[] getInts(int x, int z, int width, int height) {
        int[] aint = this.parent.getInts(x, z, width, height);
        int[] dest = IntCache.getIntCache(width * height);
        int ndx;
        int ndz;
        for (int dz = 0; dz < height; dz++) {
            for (int dx = 0; dx < width; dx++) {
                initChunkSeed(dx + x, dz + z);

                int k = aint[(dx + dz * width)];//Получение id биома
                if(k == Biome.getIdForBiome(RegBiomes.SEDIMENTARY_PLAINS)) {
                    dest[(dx + dz * width)] = this.sed_biomes[nextInt(this.sed_biomes.length)];

                } else if(k == Biome.getIdForBiome(RegBiomes.METAMORPHIC_PLAINS)) {
                    dest[(dx + dz * width)] = this.mtm_biomes[nextInt(this.mtm_biomes.length)];

                }
                else if(k == Biome.getIdForBiome(RegBiomes.MAGMATIC_PLAINS)) {
                    dest[(dx + dz * width)] = this.mgm_biomes[nextInt(this.mgm_biomes.length)];

                }



            }
        }

        return dest;
    }
}
seed -4155303313090295110
2020-04-18_15.53.17.png
 
5,018
47
783
В принципе, если их масштабировать еще пару раз, получается очень даже ничего. Но вот эти вот куски травы в пустынном биоме... Я не понимаю откуда они и почему там не сетнулся песок как везде(кстати, в этих "участочках" тоже биом как и вокруг - пустыня. Ну и еще вот эта проблема с редкостью материков, тоже удручает.
 
Последнее редактирование:
102
3
77
Полная цитата предыдущего сообщения запрещена
Ну так если биомы правильные, проблема не в генераторе биомов.
 
Последнее редактирование модератором:
5,018
47
783
Проблема по любому в слоях получается. Если генерить просто кучу биомов все сразу(без моих "регионов)", то получается вполне нормально, без вот этих странных вставок, как будто багов. Я попробовал применять к этим биомам GenLayerSmooth, но это не особо помогает. Точней вообще не помогает(
Кстати, вопрос - если я буду применять зумы после того как наложу биомы... зумится будут биомы, или вообще все?
 
Последнее редактирование:
5,018
47
783
Мне кажется, от этого же вылазит и еще одна ошибка. Вот такие вот торчащие чанки в океане. Дело в том, что я даже не знаю, что мне вообще надо дебажить, чтобы искать ошибку:cautious:
2020-04-18_19.35.54.png
 
102
3
77
Если генерить просто кучу биомов все сразу(без моих "регионов)"
Если тебе выдает отладка, что биом правильный - значит сгенерировался именно этот биом. Точнее, отдалка выдает биом из массива VoronoiZoom, а вот генерация мира происходит по родителю VoronoiZoom.

А ты понимаешь что это за слой и как он работает?
Я попробовал применять к этим биомам GenLayerSmooth

И зум как работает ты понимаешь?
если я буду применять зумы после того как наложу биомы... зумится будут биомы, или вообще все?

Я написал гайды не просто для того, чтобы они просто валялись на форуме. Я довольно часто сам их открываю, когда мне что-то нужно узнать. Не обязательно знать наизусть что и как работает, но очень важно знать где ты сможешь найти необходимую тебе инфу. Попробуй перечитать описание этих слоев. Ну или если лень, вот ответы.

Smooth просто сглаживает границы между уже существующими биомами, как-то серьезно он на них не влияет.
GenLayerZoom и GenLayerVoronoiZoom масштабирует область вне зависимости от того, что в массиве находится. Что угодно масштабируют, включая твои новые биомы. Почему так? Потому что массив чисел - это всего лишь массив чисел и алгоритму вообще насрать какую смысловую нагрузку они несут.
 
Последнее редактирование:
102
3
77
Вот такие вот торчащие чанки в океане.
Это очень странно для обычного генератора биомов, я никогда с таким не сталкивался и не уверен, что с помощью сллев реально сделать то, что ты скинул. Потому что ДАЖЕ ЕСЛИ он показывает правильный биом, но генерит неправильный, то такого перепада и разрывов не будет, т.к. дефолтный генератор МИРА все сглаживает, в каком-то смысле. Что это за мир? Overworld? Новое измерение?
 
5,018
47
783
Это мой мир, новое измерение.
Не обязательно знать что и как работает, но очень важно знать где ты сможешь найти необходимую тебе инфу. Попробуй перечитать описание этих слоев. Ну или если лень, вот ответы.
Я это читал. Я просто тупой и люблю уточнять)
И зум как работает ты понимаешь?


Ну ты на картинках в гайде достаточно наглядно показал, что он увеличивает всю область.
А ты понимаешь что это за слой и как он работает?
Я имел ввиду, что хотел применить его как костыль, чтобы эта резкость была не столь заметна. Но не получилось. )

Потому что ДАЖЕ ЕСЛИ он показывает правильный биом, но генерит неправильный, то такого перепада и разрывов не будет, т.к. дефолтный генератор МИРА все сглаживает, в каком-то смысле.
Мой чанкгенератор идентичен натуральному, на самом деле. Единственно что изменено, это заполнение чанков. Но оно работает нормально всегда, в зависимости от биома.(проверял на остальных)
Java:
public class RealismChunkGenerator extends ChunkGeneratorOverworld implements IChunkGenerator {
    public IBlockState oceanBlock = BlocksList.SALTY_WATER.getDefaultState();
    public MapGenBase caveGenerator = new RealMapGenCaves();

    public TerrainGenerator terrainGen = new TerrainGenerator();

    public RealismChunkGenerator(World worldIn, long seed, String generatorOptions) {
        super(worldIn, seed, false, generatorOptions);
        {
        
            caveGenerator = net.minecraftforge.event.terraingen.TerrainGen.getModdedMapGen(caveGenerator, net.minecraftforge.event.terraingen.InitMapGenEvent.EventType.CAVE);

            strongholdGenerator = (MapGenStronghold)net.minecraftforge.event.terraingen.TerrainGen.getModdedMapGen(strongholdGenerator, net.minecraftforge.event.terraingen.InitMapGenEvent.EventType.STRONGHOLD);

        }
    }


    @Override
    public void populate(int x, int z)
    {

        int i = x * 16 ;
        int j = z * 16;

        BlockPos pos = new BlockPos(i, 1, j);

    
        Biome biome = this.world.getBiome(pos.add(16, 0, 16));
        this.rand.setSeed(this.world.getSeed());


    }
    @Override
    public boolean generateStructures(Chunk chunkIn, int x, int z)
    {
        return false;
    }
    @Override
    public boolean isInsideStructure(World worldIn, String structureName, BlockPos pos)
    {
        return false;
    }
    @Override
    public void recreateStructures(Chunk chunkIn, int x, int z)
    {

    }
    @Override
    public void setBlocksInChunk(int x, int z, ChunkPrimer primer)
    {
    
        this.biomesForGeneration = this.world.getBiomeProvider().getBiomesForGeneration(this.biomesForGeneration, x * 4 - 2, z * 4 - 2, 10, 10);
        this.generateHeightmap(x * 4, 0, z * 4);

        for (int i = 0; i < 4; ++i)
        {
            int j = i * 5;
            int k = (i + 1) * 5;

            for (int l = 0; l < 4; ++l)
            {
                int i1 = (j + l) * 33;
                int j1 = (j + l + 1) * 33;
                int k1 = (k + l) * 33;
                int l1 = (k + l + 1) * 33;

                for (int i2 = 0; i2 < 32; ++i2)
                {
                    double d0 = 0.125D;
                    double d1 = this.heightMap[i1 + i2];
                    double d2 = this.heightMap[j1 + i2];
                    double d3 = this.heightMap[k1 + i2];
                    double d4 = this.heightMap[l1 + i2];
                    double d5 = (this.heightMap[i1 + i2 + 1] - d1) * 0.125D;
                    double d6 = (this.heightMap[j1 + i2 + 1] - d2) * 0.125D;
                    double d7 = (this.heightMap[k1 + i2 + 1] - d3) * 0.125D;
                    double d8 = (this.heightMap[l1 + i2 + 1] - d4) * 0.125D;

                    for (int j2 = 0; j2 < 8; ++j2)
                    {
                        double d9 = 0.25D;
                        double d10 = d1;
                        double d11 = d2;
                        double d12 = (d3 - d1) * 0.25D;
                        double d13 = (d4 - d2) * 0.25D;

                        for (int k2 = 0; k2 < 4; ++k2)
                        {
                            double d14 = 0.25D;
                            double d16 = (d11 - d10) * 0.25D;
                            double lvt_45_1_ = d10 - d16;

                            for (int l2 = 0; l2 < 4; ++l2)
                            {
                                if ((lvt_45_1_ += d16) > 0.0D)
                                {
                                    primer.setBlockState(i * 4 + k2, i2 * 8 + j2, l * 4 + l2, STONE);
                                }
                                else if (i2 * 8 + j2 < 63)
                                {
                                    primer.setBlockState(i * 4 + k2, i2 * 8 + j2, l * 4 + l2, this.oceanBlock);
                                }
                            }

                            d10 += d12;
                            d11 += d13;
                        }

                        d1 += d5;
                        d2 += d6;
                        d3 += d7;
                        d4 += d8;
                    }
                }
            }
        }
    }




    @Override
    public Chunk generateChunk(int x, int z)
    {
        this.rand.setSeed((long)x * 341873128712L + (long)z * 132897987541L);
        ChunkPrimer chunkprimer = new ChunkPrimer();
        this.setBlocksInChunk(x, z, chunkprimer);
        this.biomesForGeneration = this.world.getBiomeProvider().getBiomes(this.biomesForGeneration, x * 16, z * 16, 16, 16);
        this.replaceBiomeBlocks(x, z, chunkprimer, this.biomesForGeneration);

        if (this.settings.useCaves)
        {
            this.caveGenerator.generate(this.world, x, z, chunkprimer);
        }


        Chunk chunk = new Chunk(this.world, chunkprimer, x, z);
        byte[] abyte = chunk.getBiomeArray();

        for (int i = 0; i < abyte.length; ++i)
        {
            abyte[i] = (byte)Biome.getIdForBiome(this.biomesForGeneration[i]);
        }

        chunk.generateSkylightMap();
        return chunk;
    }
    @Override
    public void generateHeightmap(int x, int y, int z)
    {
        terrainGen.generateHeightmap(this, x, y, z);
    }

}
А сами чанки я заполняю прямо в классе биома. Может конечно, я тут накуролесил, но вроде бы, все было нормально обычно.
Java:
@Override
    public void genTerrainBlocks(World w, Random rand, ChunkPrimer setBIC, int x, int z, double noiseVal)
    {
        int i = w.getSeaLevel();
        int actHeight = w.getHeight(x, z);
        IBlockState topBlock = this.topBlock;
        IBlockState fillerBlock = this.fillerBlock;
        IBlockState clayBlock = this.clayBlock;
        IBlockState claystoneBlock = this.claystoneBlock;
        IBlockState stoneBlock = this.stoneBlock;
        IBlockState gravelBlock = this.gravelBlock;
        IBlockState sandBlock = this.sandBlock;
        int j = -1;
    
        int k = (int)(noiseVal / 3.0D + 3.0D + rand.nextDouble() * 0.25D);
        int chunkX = x & 15;
        int chunkZ = z & 15;


        for (int j1 = 0; j1 <= 255; ++j1)
        {

            if (j1 <= rand.nextInt(5))
            {
                setBIC.setBlockState(chunkX, j1, chunkZ, BEDROCK);
            }
            else {
  
                IBlockState chunkBlock = setBIC.getBlockState(chunkX, j1, chunkZ);
                IBlockState chunkBlockDown = setBIC.getBlockState(chunkX, j1-1, chunkZ);
                IBlockState chunkBlockUp = setBIC.getBlockState(chunkX, j1+1, chunkZ);
                if (chunkBlock.getMaterial() == Material.AIR)
                {
                    j = -1;
                }
            

                if (chunkBlock.getBlock() == Blocks.STONE && chunkBlock.getBlock() != Blocks.AIR)
                {
                    if(chunkBlock != Blocks.AIR.getDefaultState()  ) {
                        setBIC.setBlockState(chunkX, j1, chunkZ, stoneBlock);
                    }
                }
        
                if (chunkBlockDown == stoneBlock && chunkBlockUp == Blocks.AIR.getDefaultState()  )
                {
                    setBIC.setBlockState(chunkX, j1, chunkZ, topBlock);
                
                    if ( chunkBlockDown == stoneBlock && chunkBlockUp == Blocks.AIR.getDefaultState()  )
                    {
                        setBIC.setBlockState(chunkX, j1-1, chunkZ, fillerBlock);
                        setBIC.setBlockState(chunkX, j1-2, chunkZ, fillerBlock);
                        setBIC.setBlockState(chunkX, j1-3, chunkZ, fillerBlock);
                        if (chunkBlockDown == stoneBlock && chunkBlockUp == Blocks.AIR.getDefaultState()  )
                        {
                            setBIC.setBlockState(chunkX, j1-4, chunkZ, clayBlock);
                            setBIC.setBlockState(chunkX, j1-5, chunkZ, clayBlock);
                            setBIC.setBlockState(chunkX, j1-6, chunkZ, clayBlock);
                            if (chunkBlockDown == stoneBlock && chunkBlockUp == Blocks.AIR.getDefaultState()  )
                            {
                                setBIC.setBlockState(chunkX, j1-7, chunkZ, claystoneBlock);
                                setBIC.setBlockState(chunkX, j1-8, chunkZ, claystoneBlock);
                                setBIC.setBlockState(chunkX, j1-9, chunkZ, claystoneBlock);
                                setBIC.setBlockState(chunkX, j1-10, chunkZ, claystoneBlock);
                            }
                        }
                    }
                }
            }
        }}

Но основная проблема остается в том, что практически идентичный обычному мой RealGenLayerIsland генерирует острова только в случае принуждения к этому. Но тогда, можно попрощатся с океанами(
Я не знаю почему такая гадость творится. Надо попробовать с другим рандомом, что ли.
 
5,018
47
783
Попробовал. Это просто лол)
Но зато теперь наконец стало понятно откуда появляются эти торчащие чанки
2020-04-18_19.58.17.png
 
102
3
77
Твоя проблема с чанками не относится к генерации биомов, то есть вопрос данной темы себя исчерпал.
 
5,018
47
783
Исчерпал, согласен. Большое спасибо за помощь в этом вопросе.
Но она по прежнему относится к слоям! Я просто не хочу плодить темы.
У меня появилась мысль, когда я вот это увидел. Насколько я понимаю, здесь чанки двух биомов пытаются "миксоватся", но криво, потому что во-первых, слой с границами для биомов никто не создавал еще, а вторая мысль в том, что им недостаточно внимания сглаживания?

2020-04-18_20.18.31.png я увидел это.
 
102
3
77
Большое спасибо за помощь в этом вопросе.
Ага, а еще лайк(и) и лучший ответ не забудь

слой с границами для биомов никто не создавал еще
А при чем тут слой с границами биомов? Биомы рядом друг с другом и так нормально генериться могут без границ. В маине границы биомам нужны, чтобы они были похожи на биомы в реальной жизни или типа того, а не потому что там что-то плохо генерится.
 
5,018
47
783
Ну вот тут почему то не могут, видишь же сам) Проблема с этими "вырезами" очевидно, на границе биомов. А вот не было бы пустынь, я бы даже и не узнал о том, что у меня есть такая проблемс
 
Сверху