Skip to content

Creating a Module

PepperLola edited this page Jan 14, 2021 · 5 revisions

Creating a Module

Prerequisites

You should have a Java IDE (such as IntelliJ IDEA or Eclipse) installed. You should also make a fork of this repository and clone that fork locally. That is what you'll edit in order to add the module.

Creating the Module

Think of a Module

Before creating the module, make sure it's both something that people might actually want to use, as well as something that is allowed on all servers (primarily Hypixel though, because that's what this client is intended for). If it's a common module in most mainstream PvP clients, it's probably okay to add. This would include modules like ToggleSprint and Perspective Mod. They seem like they could be cheats (although newer Minecraft versions let you choose to toggle sprint), but they're included in practically all popular PvP clients. Other modules like a ping and FPS widget are most definitely not cheats. Make sure you check whether or not something would be allowed on a server (preferably Hypixel) before adding it.

Create the Class

  1. Decide which category the module falls in. For example, something that displays information on the GUI (like ping, FPS, CPS, etc.) would be in the GUI category. Something like ToggleSprint would be under movement. Freelook/perspective mod would be in util.
  2. Name the module something like <module name>Mod. For example, ToggleSprint would be ToggleSprintMod, ping display mod would be PingMod, etc. Be sure to use Pascal Case (or Upper Camel Case; the first letter of each word, including the first word, is capitalized). This is just a naming convention for Java classes, and is something you should do when naming any class in Java.
  3. Make the module class extend Module. This means that the line declaring the class should look something like public class <module name>Mod extends Module {...probably nothing but new lines at the moment...}
  4. Create a constructor for the module. The constructor should include no parameters, but your super() call should pass on the module's id, name, description, type (using the ModuleType enum), options GUI and widget. Make sure everything has proper capitalization. The id should be camelCase (same as Pascal Case but the first letter of only the first word isn't capital). The name and description should have proper capitalization (at the beginning of sentences, acronyms such as FPS, CPS, etc.). The type should be the same as the folder you put the module in (GUI, misc, util, movement, etc.). If you really think that your module doesn't fit any of those categories, you can create your own package and entry in ModuleType and use those. However, if it can fit in one of the categories, you should use that. The options GUI should be either a CustomGuiScreen if you have one or null if you don't. The widget should also be either a GuiIngameWidget or null. More on creating those later.
  5. Your IDE will likely require you to override the init method. You should override both this and the setEnabled method. Leave these blank for now; we'll come back to them later.
  6. Open the ModConfiguration file and locate the private static class DefaultValues. You'll notice there are a lot of options defined here. You'll want to find the largest group of them, the one where all of the names are something like ...ModEnabled = false;. All of the options are grouped by their type, and this group is essentially just storing whether each module is enabled. Duplicate the last line, but rename it so that it pertains to your mod (<module name>ModEnabled = false;). Make sure it's false by default, because we want to let people turn modules on by themselves instead of forcing them upon them. You'll probably want to copy the variable name (<module name>ModEnabled), because you'll be using it a lot in this file.
  • Scroll down through the file and find any time where there's a group of variables with the same names as the module enabled ones. Duplicate the last line of the group (make sure it's the right group, if only for the sake of organization), and rename the variable to the name you copied. Be sure to also add your variable to the property order. When you find a group of Property type variables, make sure you get the category right, the name should be the same as the one you copied, and the description should be similar to the others but about your own module. Then, just below the end of that group, there should be a list called propOrder.... Immediately after the declaration of that variable, we add all of those properties to the list. At the end of that addAll statement (or really the Arrays.asList call), add <name you copied>.getName(). Be sure to add a comma to then end of the previous line because it's a list.
  1. Once you finish adding the options, go back to your module class. Inside of the init method, add this.setEnabled(ModConfiguration.<name you copied>);. This just gets the saved value as to whether the module is enabled and actually sets it to be that. Inside of the setEnabled method, add these lines:
ModConfiguration.writeConfig(ModConfiguration.CATEGORY_MODS, "<name you copied>", enabled);
ModConfiguration.syncFromGUI();
super.setEnabled(enabled);

This just stores whether or not the module is enabled to the config when you toggle it. The reason you have to override both of these is because a different value is saved for each of the modules, because you want to be able to toggle them individually. 8. Open the PlayerInfo file. Find the static clause (static {...}) and duplicate the last modules.put(...) call. Replace the key with whatever id you have in your module class, and replace the value with a new instance of your module object.

Giving the Module Functionality

All of the modules are registered with the Forge event bus when the mod loads (provided they're in the modules map, so be sure you followed step 8 of the previous section). This means you can subscribe to the event bus and listen for specific events. This is what gives most modules their functionality.

  1. Think about what you want the module to do, and then find an event that would best let you do that. For example, if your module is intended to manipulate or change chat messages, you'd probably want to use the ClientChatReceivedEvent. In the Reach Display Mod, we use the AttackEntityEvent, because your reach is calculated when you hit an entity.
  2. To listen to the event, create a method with the event as a parameter, and add the @SubscribeEvent annotation. Refer to other modules for examples.
  3. If you don't know exactly how to go about doing what you're trying to do, it might be helpful to look in the event class that you're using in order to figure out which things you can use. Ctrl + click on the event class name to do that.
    If you want help developing a module, you can ask for help in the Development Help Discussion.

Note: Try not to change anything that would conflict with other modules. This could include completely modifying things like chat messages. For example, if you made it so that chat messages didn't show up in the way they normally do (<player> message) or the way they do on specific servers, that could affect the way other modules that also modify the chat parse the messages. It's completely fine if they're small changes like the text replacement mod, but try to take into account how your module affects or could affect others before you submit a pull request.

Final Steps

Be sure to test your module and try to fix any issues with it before submitting a pull request. It's alright if modules have issues after a they're merged, but only because we're working on a very small scale at the moment. It would be best to avoid having to debug the issue and trace it back to a specific commit, so it would be appreciated if you could make sure your module doesn't have any issues before you submit the pull request.
When you finish and test the module, submit a pull request on GitHub. PepperLola will revise your changes and either merge your changes or request changes.