Проблемы с производительностью при генерации мира

Версия Minecraft
1.12.2
API
Forge
428
41
108
Столкнулся с серьезными зависаниями при генерации мира, подскажите возможные решения проблемы

StructPower:
public class StructPower {
    private int power;
    public StructPower(int max){
        power = max;
    }
    public boolean use(){
        return power--<1;
    }
}

Java:
//класс AbcStruct
//то место, которое вызывает зависания
public void generate(World world, Random rand, int x, int y, int z, StructPower power) {
    if(power.use() || y>250)return;

    TemplateManager manager = worldServer.getStructureTemplateManager();
    Template template = manager.get(world.getMinecraftServer(), location);
    if(template==null)return;
   
    BlockPos pos = new BlockPos(x, y, z);
    template.addBlocksToWorldChunk(world, pos, settings);
    //тут некоторая логика, которая снова вызывает generate, если выполнится простое условие
}
 
Последнее редактирование:
428
41
108
Java:
    @Override
    public void generate(World world, Random rand, int x, int y, int z, StructPower power) {
        super.generate(world, rand, x, y, z, power);
        for(int id:subStructures){
            AbcStruct struct = buffer.get(id);   //обычная HashMap, потом заменю на обычный массив, оно не должно влиять
            if(struct!=null) {
                if (rand.nextFloat()<spawnChance) {
                    struct.generate(world, rand, x, y, z, power);
                    //вызывает тот-же generate
                }
            }
        }
    }

У меня достаточно много наследников AbcStruct, в котором и лежит ,,тормознутый,, метод.
buffer заполняется еще на этапе загрузки мода
 
Последнее редактирование:
1,369
112
241
У тебя, получается, 2 вызова generate, которые оба уходят в рекурсию: от super и от последнего условия. Немудрены лаги.
//тут некоторая логика, которая снова вызывает generate, если выполнится простое условие
Вот это место не понятно. Насколько простое условие? Меняются ли какие-либо аргументы, передаваемые в метод? Какое макс. кол-во итераций рекурсии выставлено? Выставлено ли вообще?
 
428
41
108
аргументы меняются, но там обычное сложение-вычитание. (Чтобы не уйти на 100 блоков от точки, с которой все началось) Аргументы гарантированно не будут 1 и те-же, это 100%. Оно ставит ,,домики,, либо рядом, либо друг-на-друга. Максимальная глубина рекурсии - 100 (т.е 1 ,,деревня,, не может иметь больше 100). Тестирую пока в плоском мире, с размером ,,домиков,, 4x4 блока.
 
1,369
112
241
Как я уже сказал,
super.generate(world, rand, x, y, z, power);
а после и
struct.generate(world, rand, x, y, z, power);
Приводят к тому, что у тебя появляется рекурсия в рекурсии. По-моему, это и есть основная причина провисаний.

Максимальная глубина рекурсии - 100
Помни, что майнкрафт - далеко не самая лучшая игра по технической части. Я бы поставил в райное 9-10 максимум, а может и того ниже.
 
428
41
108
Так-то оно да, у меня оно будет вставлять структуру, пока мощность не упадет до 0, или раньше, если ,,скажет рандом,,. Да, можно уменьшить мощность до 10 , но тогда в мире будут генерироваться уже совершенно другие (более примитивные) формы из структур, что меня совершенно не устраивает. Вчера я почистил код, и выиграл еще чуть-чутка процессорного времени. Но узкое место - по прежнему
template.addBlocksToWorldChunk(world, pos, settings);. Пробовал в отдельном потоке - это в некоторой части исправило, но майн стал вылетать каждые полторы минуты с ConcurrentModificationException вызванным в недрах net.minecraft.server.
 
1,369
112
241
Template сам по себе медленный. Вероятно, придётся писать свой генератор (как в том же ChocolateQuest).
И если ты не хочешь, чтобы структура генерилась в зависимости от некоего шанса, то вынеси его повыше. Так, по идее, ненужные вычисления несколько сократятся.
 
428
41
108
Заменил
template.addBlocksToWorldChunk(world, pos, settings)
На
template.addBlocksToWorld(world, pos, null, settings, 2);

BlockRotationProcessor, который использовался в первом случае, и выполняет очень много лишних (В моем случае) вычислений, и над результатом его работы тоже много лишних вычислений. Заменил его на null и куча лишней логики не выполняется. Стало работать значительно быстрее.

Так же заменил функцию рандома на ,,ленивую,, и практически избавился от тормозов
 
Сверху