You'll need to specify your own IGuiFactory class using the @Mod#guiFactory property. DefaultGuiFactory uses the GuiConfig(GuiScreen, String, String) constructor, which uses GuiConfig#collectConfigElements to create and sort the config elements, you'll need to create a similar method and use a GuiConfig constructor with a List<IConfigElement> parameter.
I found another very interesting and simple solution to this problem
Unicode has a range of codepoints called a Private Use Area. These, by definition, will never be assigned characters by the Unicode Consortium.
It also turns out that Minecraft doesn't render any characters that are in a private use area. This means that you can simply append a private use codpoint to the beginning of the name to have it sorted properly.
The first private use area ranges from E000 to F8FF, which means you can have up to 6399 config values sorted, which should be more than enough.
I created an example Gist here if anyone else wants to use it.
1
There should be some errors in the log (logs/latest.log in the game directory) explaining what went wrong, upload it to Gist and link it here.
You may want to install Forge while you're working on the model, since it greatly improves the error reporting of the model loading process. If you do, upload the FML log (logs/fml-client-latest.log in the game directory) instead of the Vanilla log.
You should also upload the model file itself and post the paths of your texture files.
1
You should create a resource pack rather than editing the vanilla files directly.
The JSON model format is documented here.
Each property in the textures block defines the value of a texture name. The block/cube model uses one texture per side, with the side's name as the texture name. The up texture is displayed on the top of the block, the east texture is displayed on the east side of the block, etc.
The texture paths are in the format "<domain>:<path/to/texture>", which corresponds to assets/<domain>/textures/<path/to/texture>.png. If you don't specify a domain, it defaults to minecraft.
1
Store the full IBlockState rather than just the Block.
JEI has code to get a TextureAtlasSprite from an IBlockState or ItemStack (this returns the particle texture) and to get a BufferedImage from a TextureAtlasSprite here.
1
You'll need to get the IBakedModel for the block and then get the texture locations from that. Either use the model's particle texture or the texture from one of the model's BakedQuads.
These texture locations are actually the names of sprites on the block texture atlas, they don't necessarily correspond to texture files on disk. This means you should get the textures from the atlas rather than reading them from a file.
1
A client-side Container shouldn't be directly interacting with the server (or scheduling a task to run on the server thread) as that would be reaching across logical sides.
You need to handle this through the sided proxy system:
As explained in the documentation I linked, World#isRemote is the way to tell which logical side code is running on.
Are you sure you need a separate thread? Can you not run this code on the main client/server thread directly?
1
Look at the Block.registerBlocks method for the registry names of vanilla Blocks (and their ItemBlocks) and look at the Item.registerItems method to see the registry names of vanilla Items (including block items that don't extend ItemBlock, like ItemSkull).
You can use an array of ingredient objects anywhere a single ingredient is expected to create a compound ingredient that matches any of the items matched by the component ingredients.
Vanilla uses this for recipes accept multiple possible items per slot (e.g. minecraft:crafting_table accepts any plank).
1
You'll need to scan each player's inventory for changes every tick on the server and then send any changes to all players tracking that player entity.
Use a capability to store the list of items that need to be synced/rendered for each player. Note that you can't use IItemHandler directly, since EntityPlayer already provides that capability itself.
I wrote this pseudocode example of how you could handle the syncing. In the packet's handler, you'd want to apply the changes from the packet to the client-side player entity's item list.
1
You shouldn't use the idea task. When creating the project, import build.gradle directly. When updating the project (e.g. adding/removing dependencies), refresh it from IDEA's Gradle window.
1
The ICustomModelLoader should return the base state of the model. The broken state can be handled by the ItemOverrideList.
The textures can either default to null (like ModelDynBucket) or be manually loaded from a file (like Tinkers' Construct's ToolModelLoader).
If the model is loaded from a blockstates file, IModel#retexture will be called with the textures specified in it; allowing you to return a new model with those textures.
ICustomModelLoader#accepts should only return true for a specific location (if you're using a single instance like ModelDynBucket) or extension (if you're loading data from a file like Tinkers' Construct). Look at the implementations of this method in ModelDynBucket.Loader and ToolModelLoader for examples. models/item isn't specific enough.
You probably don't need a cache here.
1
I had to change xlfoodmod.general.WorldGen.tooltip to xlfoodmod.general.worldgen.tooltip in the lang file to get the category tooltip working, this is because Forge coerces your field names to lowercase before using them in lang keys and subcategory names.
It turns out that Forge doesn't actually use the lang key specified for the @Config class in the config GUI if there's only one @Config class, the title is always just your mod's name. I've reported this here.