ReikaKalseki / Reika_Mods_Issues

The issue tracker for all of my mods - RotaryCraft, its addons, ChromatiCraft, and everything else.
46 stars 14 forks source link

ChromatiCraft freezes the game by using NEI on GregTech items #668

Closed xXGandalfXx closed 7 years ago

xXGandalfXx commented 8 years ago

Hey,

the game freezes completely when i look into the usage recipes of GregTech items... I don´t know if GT or CC causes this, but i think it´s Chromati... There is no crash report or something, because the i need to kill the game with task manager.

I use Chromaticraft v11b, GregTech 05.09.19 and NEI 1.0.5.120

Barhandar commented 7 years ago

The calculator has no way of knowing - semantically - what the item is or what it is for, much less how similar it is to other things.

So it's not aware of the ID, both item and modname parts?

Any way to disable the calculator/NEI integration altogether, then? I'd rather not have to wait 20+ (literal, also results in ticklag in SP, adding inability to interact with things after the freeze) minutes every time I restart the game and want to look something in 'U', or abstain from looking up usages altogether. And not seeing Chroma's things like which aura kudzu drops which item or how many lumens an item will produce in an unknown processor that is completely inaccessible at this progression stage is acceptable drawback.

ReikaKalseki commented 7 years ago

So it's not aware of the ID, both item and modname parts?

That it knows, but to what end?

Barhandar commented 7 years ago

That it knows, but to what end?

Ignore items from mod gregtech/ignore gregtech:gt.metatool.01:* (and IDs for the tool heads for metatools/recipes that involve GT item + minecraft:stick) (optionally if any matching has already been scanned), both in input and output of the recipes (and thus skip such recipes immediately).

That is, assuming the issue is in fact caused by the crafting recipes for the metatools.

...huh, going by code metatool heads are on same ID as metatools themselves. I'll check tomorrow.

ReikaKalseki commented 7 years ago

I added code to skip anything whose internal item name contains "gt.metatool".

Barhandar commented 7 years ago

That will work for recipes using metatools, and recipes producing metatools, toolheads for them are gt.metaitem.02 - which also includes turbine blades, long rods, fine wiring, rotors, gems and food.

I've just had the second freeze in same game launch, from 'U'-ing PHC apple cider (first was intentional from U on enchanting table, Ascension of the Technomancer pack). How far in both directions does it even search?

ReikaKalseki commented 7 years ago

How far in both directions does it even search?

Infinitely, stack depth notwithstanding.

Barhandar commented 7 years ago

Uh-huh. Please do cache them persistently and calculate for things missing from cache only, if possible.

ReikaKalseki commented 7 years ago

I do.

Barhandar commented 7 years ago

I mean, persistently across game quits. Slightly longer loading time for cache (if it'll be slight in comparison to full calculation) is preferable to in-game hang for a number of minutes.

Also half the items are 10-d on the lumens due to this.

ReikaKalseki commented 7 years ago

if it'll be slight in comparison to full calculation

It would not.

Barhandar commented 7 years ago

Yeah please excise GregTech altogether from the calculation. Being unable to use its machines and metals for lumens is a small price to pay for not getting frozen for half an hour total every time the game is started with errant 'U's and Ctrls (because with progression holding Ctrl over items displays lumens and has to calculate if the cache is missing).

ReikaKalseki commented 7 years ago

A better solution would be to hardcode the values of a few items, which should stop the recursive calculation.

Barhandar commented 7 years ago

How would the items to hardcode be determined?

ReikaKalseki commented 7 years ago

Someone familiar with GT would have to tell me the internal names and what they are made of and/or for.

Barhandar commented 7 years ago

Someone familiar with GT would have to tell me the internal names and what they are made of and/or for.

The problem is metaitems, and as such you cannot say what they're made of and what for at compile time. It includes anything from copper screws to steel plates to helium plasma. Only way to tell would be writing full-on GT integration that accesses its metasystem, which, uh, I believe would be far longer than "if(id.contains("gregtech") continue;" as well as probably freezing the game just as well.

https://github.com/Blood-Asp/GT5-Unofficial/blob/unstable/src/main/java/gregtech/common/items/GT_MetaGenerated_Item_01.java
https://github.com/Blood-Asp/GT5-Unofficial/blob/unstable/src/main/java/gregtech/common/items/GT_MetaGenerated_Item_02.java
https://github.com/Blood-Asp/GT5-Unofficial/blob/unstable/src/main/java/gregtech/common/items/GT_MetaGenerated_Item_03.java
https://github.com/Blood-Asp/GT5-Unofficial/blob/unstable/src/main/java/gregtech/common/items/GT_MetaGenerated_Tool_01.java

OvermindDL1 commented 7 years ago

Only way to tell would be writing full-on GT integration that accesses its metasystem, which, uh, I believe would be far longer than "if(id.contains("gregtech") continue;" as well as probably freezing the game just as well.

Actually it's system fully encodes all data into the item information so querying for stats is fairly instant.

Minecraft is horrid in how it's recipe system works, but gregtech has a duplicate of the recipe system in it's setup that is based on a hash system for near-instant lookups instead of linear like Minecraft's stock system is, but you'd have to depend on it to use that (but would make all recipe lookups significantly faster that using the stock Minecraft recipe manager), so not really a capability.

GT5 (as @Barhandar linked above) is the older GT, it does not have a lot of the additional features that GT6 does either (GT6 even uses a custom recipe handler for it's meta recipes that I alluded to that these mods could do too previously) so GT6 should not cause the issue regardless from item count since it does not expose its items via the recipe manager directly but only via shapes. GT5, however, exposes them individually, which is fine in a hashing recipe manager, but anything that iterates over a linear recipe manager (like ChC) fails on pretty hard.

ReikaKalseki commented 7 years ago

Actually it's system fully encodes all data into the item information so querying for stats is fairly instant.

Elaborate?

OvermindDL1 commented 7 years ago

GT6's (and GT5's as I recall) meta-items are items that have an 'id' (which is the 'damage' value of the itemstack) along with stats like what material it is made from and so forth encoded into the NBT, so it looks up based on that in custom recipe handlers and machine interfaces (like when right clicking a machine with a tool). Even damageable tools is just data on the NBT (the 'damage' field on an itemstack is purely for ID usage).

There are interfaces from GT that make querying item information really fast, but still, unless you actually use anything from GT there is no point and should just ignore anything that you do not explicitly handle, from any mod, not just GT.

ReikaKalseki commented 7 years ago

So in other words, I can read the NBT manually?

OvermindDL1 commented 7 years ago

So in other words, I can read the NBT manually?

Yep yep, you can see the open source to see what is stored. Or just ignore/blacklist it all. ^.^

Do note, a lot of things on the NBT are enumerations to very large and detailed lists of Material's as one example, so if you need to map specific materials you may need to hard-code a few values instead of doing those lookups.

ReikaKalseki commented 7 years ago

I know. Can I see some of these entries?

OvermindDL1 commented 7 years ago

You can dump an itemstack nbt via normal in-game means as one example, but otherwise what specific information do you want to get from the NBT? You can see the source of his entire API at http://gregtech.overminddl1.com/com/gregoriust/gregtech/gregtech_1.7.10/6.05.38/gregtech_1.7.10-6.05.38-sources.jar (or for GT5 it is similar but not as refined, and yes he has odd naming conventions but they make senseish once found out what they are).

His system overall works like:

  1. First you create a Material or grab an existing one, creating one is like:
    // Instance a new material with name Examplium
    gregapi.oredict.OreDictMaterial tExamplium = gregapi.oredict.OreDictMaterial.createMaterial(32766, "Examplium", "Examplium");
    // Give it some attributes, there are a *lot* more, everything from atomic weights to melting and
    // boiling temps to thaumcraft aspects and far far more, all done in the same way as this example,
    // which makes it smeltable in a vanilla furnace:
    tExamplium.add(gregapi.data.TD.Processing.FURNACE);
  2. Decide whether to create a new prefix (think ore or gear or something) via final gregapi.oredict.OreDictPrefix tExamplePrefix = gregapi.oredict.OreDictPrefix.createPrefix("exampleprefix"); or just use an existing one (there are a lot of existing ones to choose from). The prefix is used as the ore dictionary prefix, so a gear of steel has the ore dictionary name of gearSteel, they all follow the shapeMaterial style of naming (this is often the easiest way to find out what something is in GT, if you want a screw of iron then just accept anything that is oredict'd with screwIron, in addition to defining an ore dict with the material and shape's themselves as well).
  3. There are many types of items, many 'do' nothing, like a screw does nothing, primarily just used as recipe ingredients, to things like tools and weapons and even machines.
  4. Then to get an itemstack of an item you need to define the shape, material, and type of the item. There are utility classes that make doing this (and about anything in GT) very simple:
    • Easiest way to get a stack of, say, 20 examplium (see where I made examplium above) screws is gregapi.data.OP.screw.mat(tExamplium, 20) and the returned itemstack has all the stats set, where the 'damage' is the internal item id that defines the shape and material, and the nbt includes at this point not much for this basic call, but if it was crafted then it would include the input resources (so crafting a machine out of ingredients encodes the materials of those ingredients, so making a bronze machine encodes that it is made up of some parts of bronze of a specific amount, this is so you can melt things back down and/or disassemble them in certain ways back into what they were made instead of just generic/wrong items).

If you give a specific example of what you want to look up then I can explain in detail how that specific aspect is (but in general checking the ore dict is what you are looking for for generic shape and/or material). But use NEI with ore dictionary entries displayed and the F3+H mode to see most of the useful bits of a gregtech item.

In what cases is it useful to check for gregtech items on a pedestal anyway's I'm curious?

ReikaKalseki commented 7 years ago

In what cases is it useful to check for gregtech items on a pedestal anyway's I'm curious?

In calculating what elements are there for particle display, lumen decomposition, and so on.

ReikaKalseki commented 7 years ago

So if ore names contain useful material information, this new parser should fix the issue.

    int[] ids = OreDictionary.getOreIDs(is);
    for (int i = 0; i < ids.length; i++) {
        String name = OreDictionary.getOreName(ids[i]);
        OreType ore = ReikaItemHelper.parseOreTypeName(name);
        if (ore != null) {
            ElementTagCompound tag2 = ItemMagicRegistry.instance.getValueForOreTypeName(ore);
            if (tag2 != null)
                tag.addButMinimizeWith(tag2);
        }
    }

    if (!tag.isEmpty() || is.getItem().getUnlocalizedName().contains("gt.metatool")) { //hopefully avoid deep recursion
        return tag;
    }

public static OreType parseOreTypeName(String name) {
    Matcher m = ORE_MATERIAL_PATTERN.matcher(name);
    return m.find() ? getOreType(m.group()) : null;
}

public static OreType getOreType(String name) {
    OreType ore = ReikaOreHelper.getByEnumName(name);
    if (ore == null)
        ore = ModOreList.getByEnumName(name);
    return ore;
}