Minecraft Modding: Tips For GUI and Input

Key Binding


Check out my full tutorial at: Jabelar's Key Binding Tutorial.

General Concept For GUIs


You can open a GUI any time you want, whether it is based on something happening in the game, or a player interacting with an entity, or interacting with a block. The concept is the same in each case.

All GUIs are an instance of GuiScreen class. If you have a simple GUI you can extend GuiScreen directly, and if you have a container you should extend GuiContainer.

In the initGui() method you can create "buttons" from class GuiButton by instantiating them and adding them to the buttonList field. Note that a button really can be anything the user can interact with, so doesn't have to specifically be a button but could be slider, check box, or even an area where you paint something. Slots are handled separately (you don't need to create buttons for them) as part of making a Container for the GuiContainer.

In the updateScreen() you can process the logic for the general state of the GUI, in particular you can hide or reveal a button by setting its visible field appropriately. 

In the drawScreen() you of course draw the screen. You can use GL11 to set colors and such, use the fontRendererObj field to display text, use drawTexturedModalRect() to transfers areas of a texture resource to the screen.

The drawBackground() does what it says, but is important for GuiContainers because the GuiContainer will automatically draw the slots so if you want a graphic behind the slots you'll need to override this method.

Key Point: Things will draw in the order you code them to draw, so something drawn after will appear "in front" of the earlier thing. So if you want text in a box, draw the box then the text.

Recommendation: Check out all the draw methods in the GuiScreen class to get an idea of what you can do. You can draw text when hovering (i.e. tooltip) using the drawHovering(), draw gradients, draw the world background, and so forth.

The actionPerformed() method is very important because it is called if any of your buttons have been activated in any way. You can check for the button ID and the action type (e.g. right-click or left click) and then take the appropriate action.

Changing Vanilla GUIs


There is a GuiOpenEvent event for when the vanilla GUIs are opened. In that event you can cancel the default GUI and call your own instead.

Opening GUIs With Containers


Thanks to diesieben07 for this information.

To open a GUI with a Container you should use the player.openGui() method.

Warning: You need to be careful about what side you call the openGui() method from. If you only call that on the client, only the client will open it's GuiScreen, the server will not open the Container! If you call it on the server, the server will open the Container and then tell the client to open the GuiScreen. Alternatively you can call it on both sides, then the client will also preemptively open the GuiScreen. But you must not call it on the client only.

Blocks With GUIs


Check out my detailed tutorial: Jabelar's Blocks With GUIs Tutorial.

GUIs For Configuration Options.


Check out my full tutorial at: Jabelar's Configuration GUI Tutorial.

Create New Tab On Survival Inventory


You can use events to intercept when any GUI is opened. @SubscribeEvent to the GuiOpenEvent. Tabs are just custom rendered buttons, and if you have access to the GUI instance then you can just add buttons (custom GuiButton) to the buttonList (from GuiScreen). The GuiScreen is available as the event.gui field but unfortunately buttonList is a protected field without any getter or setter functions.

Therefore you have two options:
  1. Use Java Reflection to get the buttonList field anyway.
  2. Replace the whole GUI with a custom one that extends the same GUI class.

Draw The Texture Of An Item


See my modding tips for Items tutorial.

Adding Formatting And Color To Text and Chat


There are certain codes you can embed within a string to create formatting (colors, bold, etc.).  To do this you add an "escape character" (in this case the section symbol "§" which is also represented with
"\u00a7" and then a code character.

Here's a graphic showing the effect of different characters, for example, a "6" creates an orange ("gold") color and the "n" creates underlining.  The weird changing one is called obfuscated.




To make these a bit easier to use, there is an enumerated class called EnumChatFormatting.  For example, you can add EnumChatFormatting.RED to a string to have it display in red color.

Here is an example of a method that will make your text string a rainbow of color:

public static String stringToRainbow(String parString)
{
    int stringLength = parString.length();
    if (stringLength < 1)
    {
        return "";
    }
    String outputString = "";
    EnumChatFormatting[] colorChar = 
    {
        EnumChatFormatting.RED,
        EnumChatFormatting.GOLD,
        EnumChatFormatting.YELLOW,
        EnumChatFormatting.GREEN,
        EnumChatFormatting.AQUA,
        EnumChatFormatting.BLACK,
        EnumChatFormatting.LIGHT_PURPLE,
        EnumChatFormatting.DARK_PURPLE
    };
    for (int i = 0; i < stringLength; i++)
    {
        outputString = outputString+colorChar[i%8]+parString.substring(i, i+1);
    }
    return outputString;
}

Note that even though EnumChatFormatting is already an enumeration, I wanted the colors to be in a proper rainbow spectrum order so had to create an array to embody that.  Otherwise, I'm simply taking each character in the input string and putting in the next color in the rainbow.  Note that I use the modulo operator (%) to cycle through the colors as many times as needed depending on the length of the string.

Opening GUI From Chat Command


Thanks to diesieben07 for figuring this out.

If you ever try to make a GUI open from a chat command, you may find it doesn't work and that is because the chat command code first runs the command and then sets the GUI to null (because it wants to close the chat GUI).

So to open GUI from chat window, you'll have to implements a mechanism (maybe with client tick event) one tick later. In other words, the command sets an global int field to value of 1, client tick event would decrement that value, and if it equals 0 display the GUI, and if it equals -1 just keep it at -1.


3 comments:

  1. My girls, who beg me each day to look at all the new buildings they’ve created, broached the idea of an educational Minecraft before I could even mention it: “I like Minecraft better than my homework,” my 8-year-old told me this spring when I struggled to redirect her to that night’s math.
    How to Draw Tutorials “Maybe my homework could be on Minecraft? Like when we were learning shapes, I could go on Minecraft and make pyramids! And I could put up signs like, ‘A pyramid has a square on the bottom.’ ”

    ReplyDelete
  2. How do you check the action performed for 1.8.9?

    ReplyDelete
  3. Great article, thanks for sharing usefull information and i have seen more info on
    UI online training in Bangalore

    ReplyDelete