Real-Gecko / BornToBe

GNU General Public License v3.0
0 stars 0 forks source link

Born to Be + Biome o Plenty generate a "Exception ticking world" or null pointer exception #4

Open alxcool opened 5 years ago

alxcool commented 5 years ago

Hi! Sorry to create a new issue from what is possibly the same as [https://github.com/Real-Gecko/BornToBe/issues/2]! I'w like the chance to restart the conversation around it from what I've found so far.

Once in a while, while playing single player with a custom set of mods, there is a crash who happen during the generation of a new village. So far I've tested many different set of mods in order to reduce them to a minimum, but it seems vain... as long as Biome o Plenty and Born to Be are present, there is a % to reproduce this crash upon new village generation.

Fortunately, this kind of crash, even when generated inside a loop, could be ignored. Then, the game could be resume. Depending upon if village generation process is completed.

How to reproduce :

Note also that the possibility to avoid that crash, seems to depend on how many task is asked to the server. Bigger is the list of chunk to generate, higher is the chance to crash the game any time a village is generated.

A similar way to trigger this crash is when a village generate in a odd angle, or location. As example when a village generate on a cliff near an extreme hill. Then, once I resume the game, I could find many uncompleted building or half of one at a different Z coordinate, or rotation angle than the other.

Therefore, the more complex the code become, about structure generation, worse is the result.

Let give a closer look to the comment line in the crash report.

"java.lang.NullPointerException at com.realgecko.borntobe.VillagersHandler.handleEntityJoinWorld(VillagersHandler.java:60) at net.minecraftforge.fml.common.eventhandler.ASMEventHandler_673_VillagersHandler_handleEntityJoinWorld_EntityJoinWorldEvent.invoke(.dynamic) at net.minecraftforge.fml.common.eventhandler.ASMEventHandler.invoke(ASMEventHandler.java:90) at net.minecraftforge.fml.common.eventhandler.EventBus.post(EventBus.java:182) at net.minecraft.world.World.spawnEntity(World.java:1206) at net.minecraft.world.WorldServer.spawnEntity(WorldServer.java:1058) at net.minecraft.world.gen.structure.StructureVillagePieces$Village.spawnVillagers(StructureVillagePieces.java:1792) at net.minecraft.world.gen.structure.StructureVillagePieces$House3.addComponentParts(StructureVillagePieces.java:1193) at net.minecraft.world.gen.structure.StructureStart.generateStructure(StructureStart.java:47) at net.minecraft.world.gen.structure.MapGenStructure.generateStructure(MapGenStructure.java:94) at biomesoplenty.common.world.ChunkGeneratorOverworldBOP.populate(ChunkGeneratorOverworldBOP.java:509)"

Hypothesis :

Looks like the way trigger's library are loaded is always in the same order. For the part that concerns us, its like if VillagersHandler.java:60 is the place where "born to be" start is action, follwed by StructureVillagePieces.java:1193, then ChunkGeneratorOverworldBOP.java:509 is the place where BOP take action.

Conclusion :

Is it possible to review this mod generation code to see if there could be a conflict in the way functions are called between both mods? It may even be possible that both mod call the same library while one haven't finish using it yet.

So here a few crash files : https://paste.dimdev.org/nijohuroli.mccrash

https://paste.dimdev.org/nobopocavu.mccrash https://paste.dimdev.org/egamazigev.mccrash https://paste.dimdev.org/funuhagidi.mccrash https://paste.dimdev.org/camuzowope.mccrash https://paste.dimdev.org/waqabuwumi.mccrash latest.log

Let me know if I could help some more and good luck!

Real-Gecko commented 5 years ago

I tried to reproduce the issue for a couple of days both with and without BoP and various other mods with no luck. Everything just works. Thus no luck in fixing the issue. However I found a solution that may render this mod obsolete as it uses vanilla mechanic to spawn villagers. To make things work one needs to understand vanilla professions and careers. So, each villager has profession and can pick career from this profession. We can use VTT to add new careers without adding new professions. First we need to disable professions added by VTT, for that we go to ./minecraft/config directory and modify vtt.cfg to look like this:

# Configuration file

general {
    #  [default: [minecraft:emerald]]
    S:currencyItems <
        minecraft:emerald
     >

    #  [default: true]
    B:loadTradesFromJar=false

    #  [default: true]
    B:loadVillagersFromJar=false

    #  [default: true]
    B:sortTrades=true
}

Now we get to crucial part, go to ./minecraft/config/vtt/villagers dir and add some new careers to already existing professions. Here's what I have inside that dir: farmer.json

{
    "profession": {
        "name": "minecraft:farmer"
    },
    "careers": [
        "baker",
        "brewer"
    ]
}

smith.json

{
    "profession": {
        "name": "minecraft:smith"
    },
    "careers": [
        "redstoner"
    ]
}

As you can see I simply configured it that way, so some farmers may become baker or brewer in addition to already existing careers: fletcher, shepherd, fisherman etc. And I also configured it that way, so some smiths will turn to redstoners. And that's it! After launching the game VTT will add new careers to existing professions and will seek for trade tables in ./minecraft/config/vtt/trade_tables. MC itself will randomly assign careers to existing professions (including new ones) as it usually does on village generation. So no extra code is added, thus leading to less errors, including ones added by B2B. Here is example of my ./minecraft/config/vtt/trade_tables/baker.json

{
    "Profession": "minecraft:farmer",
    "Career": "baker",
    "Offers": {
        "Recipes": [
            {
                "action": "add",
                "buy": {
                    "id": "minecraft:wheat",
                    "Count": {
                        "min": 18,
                        "max": 22
                    }
                },
                "sell": {
                    "id": "minecraft:emerald",
                    "Count": 1
                },
                "CareerLevel": 1
            },
            {
                "action": "add",
                "buy": {
                    "id": "minecraft:sugar",
                    "Count": {
                        "min": 18,
                        "max": 22
                    }
                },
                "sell": {
                    "id": "minecraft:emerald",
                    "Count": 1
                },
                "CareerLevel": 1
            },
            {
                "action": "add",
                "buy": {
                    "id": "minecraft:egg",
                    "Count": {
                        "min": 14,
                        "max": 16
                    }
                },
                "sell": {
                    "id": "minecraft:emerald",
                    "Count": 1
                },
                "CareerLevel": 1
            },
            {
                "action": "add",
                "buy": {
                    "id": "minecraft:pumpkin",
                    "Count": {
                        "min": 8,
                        "max": 13
                    }
                },
                "sell": {
                    "id": "minecraft:emerald",
                    "Count": 1
                },
                "CareerLevel": 2
            },
            {
                "action": "add",
                "buy": {
                    "id": "minecraft:emerald",
                    "Count": {
                        "min": 2,
                        "max": 3
                    }
                },
                "sell": {
                    "id": "minecraft:pumpkin_pie",
                    "Count": 1
                },
                "CareerLevel": 2
            },
            {
                "action": "add",
                "buy": {
                    "id": "minecraft:dye",
                    "Damage": 3,
                    "Count": {
                        "min": 7,
                        "max": 12
                    }
                },
                "sell": {
                    "id": "minecraft:emerald",
                    "Count": 1
                },
                "CareerLevel": 3
            },
            {
                "action": "add",
                "buy": {
                    "id": "minecraft:emerald",
                    "Count": {
                        "min": 1,
                        "max": 1
                    }
                },
                "sell": {
                    "id": "minecraft:cake",
                    "Count": {
                        "min": 1,
                        "max": 1
                    }
                },
                "CareerLevel": 3
            },
            {
                "action": "add",
                "buy": {
                    "id": "minecraft:emerald",
                    "Count": {
                        "min": 1,
                        "max": 1
                    }
                },
                "sell": {
                    "id": "minecraft:cookie",
                    "Count": {
                        "min": 6,
                        "max": 10
                    }
                },
                "CareerLevel": 3
            }
        ]
    }
}

As you can see it is the guy who buys eggs and sells cookies :D Here are screens: image image image image image And here's smith who became redstoner instead of being armorer, weaponsmith or toolsmith: image image And here's the example from BoP: image Try it out! Maybe you won't even need this mod anymore ;)

ghost commented 5 years ago

I play with the latest version available for forge 1.12.2 and modded villagers seem to spawn naturally even without the mod! :D and how did you get a village to generate in a bop biome? image

Real-Gecko commented 5 years ago

I play with the latest version available for forge 1.12.2 and modded villagers seem to spawn naturally even without the mod! :D

That's exactly what I was talking about.

and how did you get a village to generate in a bop biome?

I dunno :D

ghost commented 5 years ago

I play with the latest version available for forge 1.12.2 and modded villagers seem to spawn naturally even without the mod! :D

That's exactly what I was talking about.

what I meant was villagers with a red robe, a blue robe, a yellow robe, etc now spawns naturally try it with forge 1.12.2 - 14.23.5.2838 the only problem is is the lack of farmers

and how did you get a village to generate in a bop biome?

I dunno :D

are you using mo villages?

Real-Gecko commented 5 years ago

Nope, it was just a testing instance with minimum mods installed.

maxanier commented 4 years ago

Not entirely sure, but it looks like https://github.com/Real-Gecko/BornToBe/blob/ae4553723cad553c5532038adef2e4b767963026/src/main/java/com/realgecko/borntobe/VillagersHandler.java#L58 this might result in trades being null as VillagerCareer#getTrades is annotated Nullable and can actually return null. Therefore the iteration at line 60 can result in the NullpointerException mentioned in the crashreport.