Changes

6,541 bytes added ,  04:01, 19 September 2020
Add Mod Structuring article

== Structuring Your Mod ==

We’ll look at how to organize your mod into different files and what those files should do.
=== Packaging ===

Pick a unique package name. If you own a URL associated with your project, you can use it as your top level package. For example if you own “example.com”, you may use <code>com.example</code> as your top level package.

{{Colored box|title=Important|content=If you do not own a domain, do not use it for your top level package. It is perfectly acceptable to start your package with anything, such as your name/nickname, or the name of the mod.}}

After the top level package (if you have one) you append a unique name for your mod, such as <code>examplemod</code>. In our case it will end up as <code>com.example.examplemod</code>.

=== The <code>mods.toml</code> file ===

This file defines the metadata of your mod. Its information may be viewed by users from the main screen of the game through the Mods button. A single info file can describe several mods.

The <code>mods.toml</code> file is formatted as [https://github.com/toml-lang/toml TOML], the example mods.toml file in the MDK provides comments explaining the contents of the file. It should be stored as <code>src/main/resources/META-INF/mods.toml</code>. A basic <code>mods.toml</code>, describing one mod, may look like this:
<syntaxhighlight lang="toml">
# The name of the mod loader type to load - for regular FML @Mod mods it should be javafml
modLoader="javafml"
# A version range to match for said mod loader - for regular FML @Mod it will be the forge version
# Forge for 1.15.2 is version 31
loaderVersion="[31,)"
# A URL to refer people to when problems occur with this mod
issueTrackerURL="github.com/MinecraftForge/MinecraftForge/issues"
# If the mods defined in this file should show as seperate resource packs
showAsResourcePack=false
[[mods]]
modId="examplemod"
version="1.0.0.0"
displayName="Example Mod"
updateJSONURL="minecraftforge.net/versions.json"
displayURL="minecraftforge.net"
logoFile="assets/examplemod/textures/logo.png"
credits="I'd like to thank my mother and father."
authors="Author"
description='''
Lets you craft dirt into diamonds. This is a traditional mod that has existed for eons. It is ancient. The holy Notch created it. Jeb rainbowfied it. Dinnerbone made it upside down. Etc.
'''

[[dependencies.examplemod]]
modId="forge"
mandatory=true
versionRange="[31,)"
ordering="NONE"
side="BOTH"

[[dependencies.examplemod]]
modId="minecraft"
mandatory=true
versionRange="[1.15.2]"
ordering="NONE"
side="BOTH"
</syntaxhighlight>
The default Gradle configuration replaces <code>${file.jarVersion}</code> with the project version, but ''only'' within <code>mods.toml</code>, so you should use those instead of directly writing them out. Here is a table of attributes that may be given to a mod, where <code>mandatory</code> means there is no default and the absence of the property causes an error.

{| class="wikitable"
|-
! Property !! Type !! Default !! Description
|-
| modid || string || mandatory || The modid this file is linked to.
|-
| version || string || mandatory || The version of the mod. It should be just numbers seperated by dots, ideally conforming to Semantic Versioning.
|-
| license || string || mandatory || The license that the mod is held under
|-
| displayName || string || mandatory || The user-friendly name of this mod.
|-
| updateJSONURL || string || "" || The URL to a version JSON.
|-
| displayURL || string || "" || A link to the mod’s homepage.
|-
| logoFile || string || "" || The filename of the mod’s logo. It must be placed in the root resource folder, not in a subfolder.
|-
| credits || string || "" || A string that contains any acknowledgements you want to mention.
|-
| authors || string || "" || The authors to this mod.
|-
| description || string || mandatory || A description of this mod.
|-
| dependencies || [list] || [] || A list of dependencies of this mod.
|}

NOTE: All version ranges use the [https://maven.apache.org/enforcer/enforcer-rules/versionRanges.html Maven Version Range Specification].

=== The Mod File ===

Generally, we’ll start with a file named after your mod, and put into your package. This is the ''entry point'' to your mod and will contain some special indicators marking it as such.

==== What is <code>@Mod</code>? ====

This is an annotation indicating to the Forge Mod Loader that the class is a Mod entry point. The <code>@Mod</code> annotation’s value should match a mod id in the <code>src/main/resources/META-INF/mods.toml</code> file.

==== Keeping Your Code Clean Using Sub-packages ====

Rather than clutter up a single class and package with everything, it is recommended you break your mod into subpackages.

A common subpackage strategy has packages for <code>common</code> and <code>client</code> code, which is code that can be run on server/client and client, respectively. Inside the <code>common</code> package would go things like Items, Blocks, and Tile Entities (which can each in turn be another subpackage). Things like GUIs and Renderers would go inside the <code>client</code> package.

{{Colored box|title=Note|content=This package style is only a suggestion, though it is a commonly used style. Feel free to use your own packaging system.}}

By keeping your code in clean subpackages, you can grow your mod much more organically.

==== Class Naming Schemes ====

A common class naming scheme allows easier deciphering of what a class is, and also makes it easier for someone developing with your mod to find things.

For Example:

* An <code>Item</code> called <code>PowerRing</code> would be in an <code>item</code> package, with a class name of <code>PowerRingItem</code>.
* A <code>Block</code> called <code>NotDirt</code> would be in a <code>block</code> package, with a class name of <code>NotDirtBlock</code>.
* Finally, a <code>TileEntity</code> for a block called <code>SuperChewer</code> would be in a <code>tile</code> or <code>tileentity</code> package, with a class name of <code>SuperChewerTile</code>.

Appending your class names with what ''kind'' of object they are makes it easier to figure out what a class is, or guess the class for an object.

[[Category:Getting Started]]