Chunk.checkLight() потребляет слишком много мощности игры и вызывает большие просадки TPS

Версия Minecraft
1.12.2
API
Forge
26
2
2
Всех приветствую!

Я тут решил сделать маленький такой генератор мира.
Для него мне нужен потолок и пол из бедрока.
Я это успешно реализовал. Но тут возник вопрос с оптимизацией...
Дело в том, что когда генерируется новый чанк, он вызывает функцию Chunk.checkLight(), что очень сильно просаживает TPS (при активной нагрузке - до 6 тиков в секунду, что очень плохо!)
Вот лог профайлера: spark
А на случай удаления лога вот скриншот:
1701976458970.png

Ну и вот как выглядит сам мир:
1701976512307.png

Вот код.

Как исправить эту проблему?
 
Решение
Как это исправить? Ну, чтобы при создании в моём генераторе, overworld генерировался по моему WorldProvider (точнее, как измерение ancientcaves)

Останется только принудительно заставить DimensionManager создать этот провайдер (с помощью миксинов) по id=0, тк у тебя это не измерение а ,,нормальный мир,,
378
37
92
Для него мне нужен потолок и пол из бедрока.
Переопредели метод hasSkyLight() у провайдера мира, чтобы возвращал false

(в следующий раз лучше сюда код дублируй - так сказать для потомков)
 
378
37
92
378
37
92
Тьфу, перепутал, в голове одни биомы ..

Java:
package plus.space.common.world.pro;

import net.minecraft.client.Minecraft;
import net.minecraft.world.DimensionType;
import net.minecraft.world.WorldProvider;
import net.minecraft.world.biome.BiomeProviderSingle;
import net.minecraft.world.gen.IChunkGenerator;
import net.minecraftforge.client.IRenderHandler;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import plus.space.client.OrbitSkyRenderer;

//лень делать пример, вытащил рабочий код из своих архивов
public class EOrbitProvider extends WorldProvider {
    public static DimensionType ORBIT;

    public static void registerIfNeed(){
        if(ORBIT != null)return;
        ORBIT = DimensionType.register("orbit", "orbit", 1001, EOrbitProvider.class, false);
    }


    @Override
    protected void init() {
        this.hasSkyLight = true;
        this.biomeProvider = new BiomeProviderSingle(BiomeOrbit.ORBIT);
    }


    public int getAverageGroundLevel() {
        return 16;
    }


    @SideOnly(Side.CLIENT)
    private OrbitSkyRenderer renderer;
    @Override
    @SideOnly(Side.CLIENT)
    public IRenderHandler getSkyRenderer() {
        if(renderer==null){
            renderer = new OrbitSkyRenderer(Minecraft.getMinecraft());
        }
        return renderer;
    }


    @SideOnly(Side.CLIENT)
    public float calculateCelestialAngle(long worldTime, float partialTicks) {
        if(renderer==null) {
            return super.calculateCelestialAngle(worldTime, partialTicks);
        } else {
            return renderer.getWorldCel(worldTime, partialTicks);
        }
    }


    @SideOnly(Side.CLIENT)
    public float getCloudHeight() {
        return 8.0F;
    }


    @Override
    public DimensionType getDimensionType() {
        return ORBIT;
    }


    @Override
    public IChunkGenerator createChunkGenerator() {
        throw new UnsupportedOperationException();
    }
}

Останется только принудительно заставить DimensionManager создать этот провайдер (с помощью миксинов) по id=0, тк у тебя это не измерение а ,,нормальный мир,,
 
26
2
2
Теперь краш появился)
Регистрирую измерение я без MixIn'ов.
Java:
---- Minecraft Crash Report ----
// Uh... Did I do that?

Time: 12/8/23 6:36 PM
Description: Exception ticking world

java.lang.NullPointerException: Exception ticking world
    at net.minecraft.world.WorldServer.tick(WorldServer.java:186)
    at net.minecraft.server.MinecraftServer.updateTimeLightAndEntities(MinecraftServer.java:756)
    at net.minecraft.server.MinecraftServer.tick(MinecraftServer.java:668)
    at net.minecraft.server.integrated.IntegratedServer.tick(IntegratedServer.java:185)
    at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:526)
    at java.lang.Thread.run(Thread.java:750)


A detailed walkthrough of the error, its code path and all known details is as follows:
---------------------------------------------------------------------------------------

-- Head --
Thread: Server thread
Stacktrace:
    at net.minecraft.world.WorldServer.tick(WorldServer.java:186)

-- Affected level --
Details:
    Level name: New Worldsdf
    All players: 0 total; []
    Chunk stats: ServerChunkCache: 0 Drop: 0
    Level seed: 1553330326481045570
    Level generator: ID 00 - default, ver 1. Features enabled: false
    Level generator options:
    Level spawn location: World: (0,0,0), Chunk: (at 0,0,0 in 0,0; contains blocks 0,0,0 to 15,255,15), Region: (0,0; contains chunks 0,0 to 31,31, blocks 0,0,0 to 511,255,511)
    Level time: 0 game time, 0 day time
    Level dimension: 0
    Level storage version: 0x00000 - Unknown?
    Level weather: Rain time: 0 (now: false), thunder time: 0 (now: false)
    Level game mode: ~~ERROR~~ NullPointerException: null
Stacktrace:
    at net.minecraft.server.MinecraftServer.updateTimeLightAndEntities(MinecraftServer.java:756)
    at net.minecraft.server.MinecraftServer.tick(MinecraftServer.java:668)
    at net.minecraft.server.integrated.IntegratedServer.tick(IntegratedServer.java:185)
    at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:526)
    at java.lang.Thread.run(Thread.java:750)

-- System Details --
Details:
    Minecraft Version: 1.12.2
    Operating System: Linux (amd64) version 6.2.0-37-generic
    Java Version: 1.8.0_382, Amazon.com Inc.
    Java VM Version: OpenJDK 64-Bit Server VM (mixed mode), Amazon.com Inc.
    Memory: 753849480 bytes (718 MB) / 1191182336 bytes (1136 MB) up to 3698851840 bytes (3527 MB)
    JVM Flags: 0 total;
    IntCache: cache: 0, tcache: 0, allocated: 0, tallocated: 0
    FML: MCP 9.42 Powered by Forge 14.23.5.2860 6 mods loaded, 6 mods active
    States: 'U' = Unloaded 'L' = Loaded 'C' = Constructed 'H' = Pre-initialized 'I' = Initialized 'J' = Post-initialized 'A' = Available 'D' = Disabled 'E' = Errored

    | State  | ID           | Version      | Source                                                             | Signature |
    |:------ |:------------ |:------------ |:------------------------------------------------------------------ |:--------- |
    | LCHIJA | minecraft    | 1.12.2       | minecraft.jar                                                      | None      |
    | LCHIJA | mcp          | 9.42         | minecraft.jar                                                      | None      |
    | LCHIJA | FML          | 8.0.99.99    | forge-1.12.2-14.23.5.2860_mapped_snapshot_20171003-1.12-recomp.jar | None      |
    | LCHIJA | forge        | 14.23.5.2860 | forge-1.12.2-14.23.5.2860_mapped_snapshot_20171003-1.12-recomp.jar | None      |
    | LCHIJA | ancientcaves | 1.0          | main                                                               | None      |
    | LCHIJA | spark        | 1.6.3        | spark-forge.jar                                                    | None      |

    Loaded coremods (and transformers):
    GL info: ~~ERROR~~ RuntimeException: No OpenGL context found in the current thread.
    Profiler Position: N/A (disabled)
    Player Count: 0 / 8; []
    Type: Integrated Server (map_client.txt)
    Is Modded: Definitely; Client brand changed to 'fml,forge'

Java:
package ru.aloyenz.ancientcaves.world;

import net.minecraft.world.DimensionType;
import net.minecraft.world.WorldProvider;
import net.minecraft.world.gen.IChunkGenerator;
import net.minecraftforge.common.DimensionManager;

public class AncientCavesWorldProvider extends WorldProvider {
    public static DimensionType ANCIENT_CAVES;

    public static void registerIfNeed(){
        if(ANCIENT_CAVES != null)return;
        ANCIENT_CAVES = DimensionType.register("ancientcaves", "ancientcaves", 912,
                AncientCavesWorldProvider.class, false);
        DimensionManager.registerDimension(912, ANCIENT_CAVES);
    }

//    @Override
//    protected void init() {
//        this.hasSkyLight = false;
//    }

    @Override
    public boolean hasSkyLight() {
        return false;
    }


    public int getAverageGroundLevel() {
        return 128;
    }


    @Override
    public DimensionType getDimensionType() {
        return ANCIENT_CAVES;
    }


    @Override
    public IChunkGenerator createChunkGenerator() {
        return new AncientCavesGenerator(world);
    }
}
Конструктор WorldType:
    public AncientCavesWorldType() {
        super("ac");

        AncientCavesWorldProvider.registerIfNeed();
    }
Конструктор IChunkGenerator'а:
    public AncientCavesGenerator(World worldIn) {
        this.world = worldIn;
        this.random = new Random(worldIn.getSeed());
        DimensionManager.setWorld(912, (WorldServer) worldIn,
                Objects.requireNonNull(worldIn.getMinecraftServer()));
    }
 
26
2
2
Я забыл там добавить BiomeProvider. Я это сделал.
Мир создался... Но у меня теперь четыре измерения. Это overworld, два неинтересующих и ancientcaves.
Последнее не лагает. Но когда я создаю мир своего типа, то меня кидает в overworld, в котором всё ещё присутствует лагучий свет.
Прикреплю скриншот...
1702052004614.png

Как это исправить? Ну, чтобы при создании в моём генераторе, overworld генерировался по моему WorldProvider (точнее, как измерение ancientcaves)
 
378
37
92
Как это исправить? Ну, чтобы при создании в моём генераторе, overworld генерировался по моему WorldProvider (точнее, как измерение ancientcaves)

Останется только принудительно заставить DimensionManager создать этот провайдер (с помощью миксинов) по id=0, тк у тебя это не измерение а ,,нормальный мир,,
 
Сверху