<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-GB">
	<id>https://forge.gemwire.uk/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=N1K-x</id>
	<title>Forge Community Wiki - User contributions [en-gb]</title>
	<link rel="self" type="application/atom+xml" href="https://forge.gemwire.uk/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=N1K-x"/>
	<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/wiki/Special:Contributions/N1K-x"/>
	<updated>2026-05-15T13:45:26Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.35.0</generator>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Mods.toml&amp;diff=3099</id>
		<title>Mods.toml</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Mods.toml&amp;diff=3099"/>
		<updated>2021-12-11T17:08:48Z</updated>

		<summary type="html">&lt;p&gt;N1K-x: Update to 1.18.1&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Under construction}}&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;mods.toml&amp;lt;/code&amp;gt; file is read by the mod loader to determine what mods are packaged into your JAR file, and what information to display to the user in the Mods listing screen (accessible by pressing the &amp;quot;Mods&amp;quot; button on the main menu of the game). &lt;br /&gt;
&lt;br /&gt;
The file is formatted in [https://toml.io/en/ Tom's Obvious Minimal Language], or TOML for short. The example &amp;lt;code&amp;gt;mods.toml&amp;lt;/code&amp;gt; file in the MDK provides comments explaining the contents of the file. It should be stored under the &amp;lt;code&amp;gt;META-INF&amp;lt;/code&amp;gt; folder in your resources directory (&amp;lt;code&amp;gt;src/main/resources/META-INF/mods.toml&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Example &amp;lt;code&amp;gt;mods.toml&amp;lt;/code&amp;gt; file:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;TOML&amp;quot;&amp;gt;&lt;br /&gt;
modLoader=&amp;quot;javafml&amp;quot;&lt;br /&gt;
# Forge for 1.18.1 is version 39&lt;br /&gt;
loaderVersion=&amp;quot;[39,)&amp;quot;&lt;br /&gt;
license=&amp;quot;All rights reserved&amp;quot;&lt;br /&gt;
issueTrackerURL=&amp;quot;github.com/MinecraftForge/MinecraftForge/issues&amp;quot;&lt;br /&gt;
showAsResourcePack=false&lt;br /&gt;
&lt;br /&gt;
[[mods]]&lt;br /&gt;
    modId=&amp;quot;examplemod&amp;quot;&lt;br /&gt;
    version=&amp;quot;1.0.0.0&amp;quot;&lt;br /&gt;
    displayName=&amp;quot;Example Mod&amp;quot;&lt;br /&gt;
    updateJSONURL=&amp;quot;minecraftforge.net/versions.json&amp;quot;&lt;br /&gt;
    displayURL=&amp;quot;minecraftforge.net&amp;quot;&lt;br /&gt;
    logoFile=&amp;quot;logo.png&amp;quot;&lt;br /&gt;
    credits=&amp;quot;I'd like to thank my mother and father.&amp;quot;&lt;br /&gt;
    authors=&amp;quot;Author&amp;quot;&lt;br /&gt;
    description='''&lt;br /&gt;
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.&lt;br /&gt;
    '''&lt;br /&gt;
&lt;br /&gt;
[[dependencies.examplemod]]&lt;br /&gt;
    modId=&amp;quot;forge&amp;quot;&lt;br /&gt;
    mandatory=true&lt;br /&gt;
    versionRange=&amp;quot;[39,)&amp;quot;&lt;br /&gt;
    ordering=&amp;quot;NONE&amp;quot;&lt;br /&gt;
    side=&amp;quot;BOTH&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[[dependencies.examplemod]]&lt;br /&gt;
    modId=&amp;quot;minecraft&amp;quot;&lt;br /&gt;
    mandatory=true&lt;br /&gt;
    versionRange=&amp;quot;[1.18.1,1.19)&amp;quot;&lt;br /&gt;
    ordering=&amp;quot;NONE&amp;quot;&lt;br /&gt;
    side=&amp;quot;BOTH&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the &amp;lt;code&amp;gt;version&amp;lt;/code&amp;gt; is specified as&amp;lt;code&amp;gt;${file.jarVersion}&amp;lt;/code&amp;gt;, Forge will replace the string with the 'Implementation Version' specified in the jar manifest at runtime. Since the userdev environment has no jar manifest to pull from, it will be &amp;lt;code&amp;gt;NONE&amp;lt;/code&amp;gt; instead. As such, it is usually recommended to leave this field alone.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;mods.toml&amp;lt;/code&amp;gt; is split into three parts: the non-mod-specific properties, which are linked to the mod file; the mod properties, with a section for each mod; and dependency configurations, with a section for each mod's dependencies. Here is a table of attributes that may be given to a mod, where &amp;lt;code&amp;gt;mandatory&amp;lt;/code&amp;gt; means there is no default and the absence of the property causes an error.&lt;br /&gt;
&lt;br /&gt;
===Non-Mod-Specific Properties===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!|Property&lt;br /&gt;
!|Type&lt;br /&gt;
!|Defaults&lt;br /&gt;
!|Description&lt;br /&gt;
!|Example&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;modLoader&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|'''mandatory'''&lt;br /&gt;
|The language loader for the mod. Used to specify an alternative language for the mod, such as Kotlin, if one exists. The Forge-provided Java loader is &amp;lt;code&amp;gt;javafml&amp;lt;/code&amp;gt;.&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;javafml&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;loaderVersion&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|'''mandatory'''&lt;br /&gt;
|The acceptable version range of the language loader, expressed as a [https://maven.apache.org/enforcer/enforcer-rules/versionRanges.html Maven version spec]. For the Forge-provided Java loader, the version is the major version of the Forge version.&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;[39,)&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;license&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|'''mandatory'''&lt;br /&gt;
|The license for the mod(s) in this JAR. This string may be any valid string, but it is suggested to set the value to be the name of your license, and/or a link to that license.&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;GNU GPL v3, https://www.gnu.org/licenses/gpl-3.0.en.html&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;showAsResourcePack&amp;lt;/code&amp;gt;&lt;br /&gt;
|boolean&lt;br /&gt;
|&amp;lt;code&amp;gt;false&amp;lt;/code&amp;gt;&lt;br /&gt;
|Whether to display this mod's resources as a separate option in the resource pack menu. If disabled, the mod's resources will be rolled into the &amp;quot;Mod resources&amp;quot; pack.&lt;br /&gt;
|&amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;properties&amp;lt;/code&amp;gt;&lt;br /&gt;
|table&lt;br /&gt;
|&amp;lt;code&amp;gt;{}&amp;lt;/code&amp;gt;&lt;br /&gt;
|A table of custom substitution properties. This is used by &amp;lt;code&amp;gt;StringSubstitutor&amp;lt;/code&amp;gt; to replace values, using &amp;lt;code&amp;gt;${file.*}&amp;lt;/code&amp;gt;.&lt;br /&gt;
|&amp;lt;code&amp;gt;{ &amp;quot;thingy&amp;quot; = 1 }&amp;lt;/code&amp;gt;, used in &amp;lt;code&amp;gt;${file.thingy}&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;issueTrackerURL&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|''nothing''&lt;br /&gt;
|A URL for an issues tracker. This should never be a blank string, as that will cause an error.&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&amp;quot;http://my.issue.tracker/&amp;quot;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Mod Properties===&lt;br /&gt;
A mod entry is defined by a new section starting with a &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;[[mods]]&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; header (In TOML, the &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;[[mods]]&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; defines an [https://toml.io/en/v1.0.0-rc.2#array-of-tables array of tables]). All properties from that line until the next header will become the properties for that mod.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!|Property&lt;br /&gt;
!|Type&lt;br /&gt;
!|Defaults&lt;br /&gt;
!|Description&lt;br /&gt;
!|Example&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;modId&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|'''mandatory'''&lt;br /&gt;
|The mod's identifier (modid). This must match the following regex: &amp;lt;code&amp;gt;^[a-z][a-z0-9_-]{1,63}$&amp;lt;/code&amp;gt; (starts with a lowercase letter; other characters must be a lowercase letter, number, underscore or hyphen; must be 2-64 characters long).&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;examplemod&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;namespace&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|value of &amp;lt;code&amp;gt;modId&amp;lt;/code&amp;gt;&lt;br /&gt;
|An override namespace. Currently, there is no use for this property&lt;br /&gt;
|&amp;lt;code&amp;gt;example&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;version&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;1&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|The mod's version, ideally conforming to [[Semantic Versioning|semantic versioning]]. The default value in the MDK for this is &amp;lt;code&amp;gt;${file.jarVersion}&amp;lt;/code&amp;gt;, which is replaced at runtime with the &amp;lt;code&amp;gt;Implementation-Version&amp;lt;/code&amp;gt; found in the jar's manifest file.&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;0.2.4-beta1&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;displayName&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|value of &amp;lt;code&amp;gt;modId&amp;lt;/code&amp;gt;&lt;br /&gt;
|The display name of the mod, for use in the Mods listing screen&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;Example Mod&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;description&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;MISSING DESCRIPTION&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|The description of the mod, for use in the Mods listing screen. It's recommended to use a multiline string (surrounded by &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;'''&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;)&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;Adds things and stuff. &amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;logoFile&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|''nothing''&lt;br /&gt;
|The path of the logo file image, for use in the Mods listing screen. The image must be in the root of the jar file, not in any subfolder thereof (e.g. the file is directly in &amp;lt;code&amp;gt;src/main/resources&amp;lt;/code&amp;gt;)&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;myAwesomeLogo.png&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;logoBlur&amp;lt;/code&amp;gt;&lt;br /&gt;
|boolean&lt;br /&gt;
|&amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;&lt;br /&gt;
|Whether to do some blurring on the mod's logo in the Mods listing screen. Has no effect if &amp;lt;code&amp;gt;logoFile&amp;lt;/code&amp;gt; is not set.&lt;br /&gt;
|&amp;lt;code&amp;gt;false&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;updateJSONURL&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|''nothing''&lt;br /&gt;
|The update JSON URL, used by the [[Update_Checker|update checker]]. This should never be a blank string, as that will cause an error.&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&amp;quot;http://myurl.me/path/to/update.json&amp;quot;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;modproperties&amp;lt;/code&amp;gt;&lt;br /&gt;
|table&lt;br /&gt;
|&amp;lt;code&amp;gt;{}&amp;lt;/code&amp;gt;&lt;br /&gt;
|A table of custom mod properties; this is not used for Forge, but is mainly for use by mods.&lt;br /&gt;
|&amp;lt;code&amp;gt;{ &amp;quot;useThing&amp;quot; = true }&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;credits&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|''nothing''&lt;br /&gt;
|Credits and acknowledgements for the mod, for use in the Mods listing screen. Can be any string.&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;This person and that guy&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;authors&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|''nothing''&lt;br /&gt;
|Authors for the mod, for use in the Mods listing screen. Can be any string.&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;ExampleDude&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;displayURL&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|''nothing''&lt;br /&gt;
|A URL, displayed on the Mods listing screen. Can be any string.&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&amp;quot;http://example.com/&amp;quot;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Dependency Configurations===&lt;br /&gt;
Mods can define dependencies for their mods, which are checked by Forge before loading mods. This is used for e.g. ensuring your mod loads after another, or hard-crashing if a mod with a specified version does not exist.&lt;br /&gt;
&lt;br /&gt;
These dependency configurations, like the mod properties, are defined by a new section starting with &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;[[dependencies.modid]]&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;, with &amp;lt;code&amp;gt;modid&amp;lt;/code&amp;gt; being the mod id that has this dependency. All properties from that line until the next header will become the properties of that dependency configuration.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!|Property&lt;br /&gt;
!|Type&lt;br /&gt;
!|Defaults&lt;br /&gt;
!|Description&lt;br /&gt;
!|Example&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;modId&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|'''mandatory'''&lt;br /&gt;
|The mod id of the dependency.&lt;br /&gt;
|&amp;lt;code&amp;gt;examplelibrary&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mandatory&amp;lt;/code&amp;gt;&lt;br /&gt;
|boolean&lt;br /&gt;
|'''mandatory'''&lt;br /&gt;
|Whether to crash if this dependency is not met.&lt;br /&gt;
|&amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;versionRange&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|The acceptable version range of the dependency, expressed as a [https://maven.apache.org/enforcer/enforcer-rules/versionRanges.html Maven version spec]. An empty string is an unbounded version range, which matches any version.&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;[1.0,2.0)&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;ordering&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;NONE&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|Defines if the mod must load before or after this dependency. The valid values are &amp;lt;code&amp;gt;BEFORE&amp;lt;/code&amp;gt; (must load before), &amp;lt;code&amp;gt;AFTER&amp;lt;/code&amp;gt; (must load after), and &amp;lt;code&amp;gt;NONE&amp;lt;/code&amp;gt; (does not care about order).&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;AFTER&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;side&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;BOTH&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|physical side]]. The valid values are &amp;lt;code&amp;gt;CLIENT&amp;lt;/code&amp;gt; (present on the client), &amp;lt;code&amp;gt;SERVER&amp;lt;/code&amp;gt; (present on the dedicated server), and &amp;lt;code&amp;gt;BOTH&amp;lt;/code&amp;gt; (present on both sides).&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;CLIENT&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Tip/Warning|When specifying dependency ordering between two or more mods, beware of cyclic order!&lt;br /&gt;
An example: if mod A must load before mod B, and mod B must load before mod A, the game will crash because of the circular cycle.}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Getting Started]]&lt;br /&gt;
[[Category:Beginner Topics]]&lt;/div&gt;</summary>
		<author><name>N1K-x</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Capabilities&amp;diff=3098</id>
		<title>Capabilities</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Capabilities&amp;diff=3098"/>
		<updated>2021-12-10T14:41:48Z</updated>

		<summary type="html">&lt;p&gt;N1K-x: Update the code example Gist to the new version&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Capabilities''' are a Forge system that allows cross-mod interactions by allowing capability ''providers'' to&lt;br /&gt;
dynamically respect contracts and provide specialized behavior without requiring the implementation of many interfaces&lt;br /&gt;
or hard dependencies on mods.&lt;br /&gt;
&lt;br /&gt;
== History ==&lt;br /&gt;
In an ideal world, all that would be needed for a mod to provide the equivalent of a capability would be implementing an&lt;br /&gt;
interface. This is in fact how cross-mod interaction used to work prior to the introduction of capabilities.&lt;br /&gt;
&lt;br /&gt;
The real world, though, is often much more complicated: users wanted to be free to combine mods the way they wanted and&lt;br /&gt;
saw fit, and developers wanted to be able to declare ''soft'' dependencies on other mods, thus reducing the need of&lt;br /&gt;
having a huge mod pack just for testing.&lt;br /&gt;
&lt;br /&gt;
The first approach used by Forge was conditional stripping of interfaces and methods, but this proved to be problematic.&lt;br /&gt;
While the idea works well in theory, in practice the ASM editing of classes relied on complex mechanics and could lead&lt;br /&gt;
to hard to spot bugs.&lt;br /&gt;
&lt;br /&gt;
For this reason, the entire system was redesigned and the concept of '''capabilities''' was born.&lt;br /&gt;
&lt;br /&gt;
== The Concept ==&lt;br /&gt;
A capability allows any capability provider to conditionally expose a certain ability to do something, e.g. accepting&lt;br /&gt;
power or handling items. A capability provider, moreover, can decide to expose a capability only on certain sides,&lt;br /&gt;
allowing for easy interactions with hoppers, cables, etc.&lt;br /&gt;
&lt;br /&gt;
Capabilities may also be added and removed dynamically both from the &amp;quot;owner&amp;quot; of the capability provider and other mods,&lt;br /&gt;
allowing even easier cross-mod interaction. For example, a mod that isn't compatible with Forge Energy could be&lt;br /&gt;
converted into one by dynamically attaching the Forge Energy capability and handling the conversion to a third-party&lt;br /&gt;
energy system without having to alter the original mod.&lt;br /&gt;
&lt;br /&gt;
== Terminology ==&lt;br /&gt;
The high flexibility of the system comes with a cost, though, which is terminology. The following section wants to be a&lt;br /&gt;
dictionary of sorts, defining all the terms that you may come across when dealing with capabilities.&lt;br /&gt;
&lt;br /&gt;
In the rest of this article, we will refer to these terms frequently, so make sure you are familiar with them.&lt;br /&gt;
&lt;br /&gt;
; Capability&lt;br /&gt;
: the ability to perform something. In-code this is represented by the &amp;lt;code&amp;gt;Capability&amp;lt;/code&amp;gt; class.&lt;br /&gt;
; Capability Provider&lt;br /&gt;
: something that is able to support capabilities and provides a mean of accessing them. In-code they are represented by implementations of &amp;lt;code&amp;gt;ICapabilityProvider&amp;lt;/code&amp;gt;. There are multiple kinds of capability providers:&lt;br /&gt;
:; Volatile Provider&lt;br /&gt;
:: a provider that doesn't persist data to disk; once the provider ceases to exist for any number of reasons, all capability data gets deleted.&lt;br /&gt;
:; Persistent Provider&lt;br /&gt;
:: a provider that requires all capabilities to serialize data to disk, in order to persist data even across game restarts. They implement the &amp;lt;code&amp;gt;INBTSerializable&amp;lt;/code&amp;gt; interface.&lt;br /&gt;
:; Agnostic Provider&lt;br /&gt;
:: a provider that isn't neither volatile nor persistent, rather delegates the decision either to the capability directly or to sub-implementations. They also implement the &amp;lt;code&amp;gt;INBTSerializable&amp;lt;/code&amp;gt; interface.&lt;br /&gt;
; Capability Interface&lt;br /&gt;
: the interface that defines the contract of the capability, so what operations the capability exposes.&lt;br /&gt;
; Capability Implementation&lt;br /&gt;
: one of the possibly many implementations of the capability interface, that actually carries out the work.&lt;br /&gt;
&lt;br /&gt;
The wary reader may note that both ''persistent'' and ''agnostic'' providers are represented the same way in code. In&lt;br /&gt;
fact, the only difference between them comes from pure semantics in how their serialization methods are designed. This&lt;br /&gt;
will be further discussed in their respective sections.&lt;br /&gt;
&lt;br /&gt;
Moreover, it is also common to refer to the capability interface as simply the ''capability''. While not strictly&lt;br /&gt;
correct, due to common usage we will also use this convention. So, to refer to the capability interface&lt;br /&gt;
&amp;lt;code&amp;gt;MyCapability&amp;lt;/code&amp;gt;, we will usually talk about the &amp;quot;&amp;lt;code&amp;gt;MyCapability&amp;lt;/code&amp;gt; capability&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Forge-provided Capabilities and Providers ==&lt;br /&gt;
In order to ensure mods can work together seamlessly, Forge provides a set of default capabilities and capability&lt;br /&gt;
providers.&lt;br /&gt;
&lt;br /&gt;
The default capability providers in a Forge environment are: &amp;lt;code&amp;gt;BlockEntity&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Entity&amp;lt;/code&amp;gt;,&lt;br /&gt;
&amp;lt;code&amp;gt;ItemStack&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Level&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;LevelChunk&amp;lt;/code&amp;gt;. These are all agnostic providers, since they don't&lt;br /&gt;
mandate any sort of capability persistency requirements. Rather, it is the job of whoever subclasses these providers to&lt;br /&gt;
deal with either volatile or non-volatile capabilities.&lt;br /&gt;
&lt;br /&gt;
The default capabilities that forge provides are represented by the interfaces &amp;lt;code&amp;gt;IItemHandler&amp;lt;/code&amp;gt;,&lt;br /&gt;
&amp;lt;code&amp;gt;IFluidHandler&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;IFluidHandlerItem&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;IEnergyStorage&amp;lt;/code&amp;gt;, and&lt;br /&gt;
&amp;lt;code&amp;gt;IAnimationStateMachine&amp;lt;/code&amp;gt;. Each one of these capabilities will be discussed in the corresponding section.&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;tt&amp;gt;IItemHandler&amp;lt;/tt&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;IItemHandler&amp;lt;/code&amp;gt; capability refers to the ability for any capability provider to have some sort of internal&lt;br /&gt;
'''inventory''' with a certain number of slots, from which items can be inserted and extracted. It is also possible,&lt;br /&gt;
though, to expose this capability even if no such inventory is present as long as the capability provider can emulate&lt;br /&gt;
its presence (e.g. tools that allow accessing remote inventories).&lt;br /&gt;
&lt;br /&gt;
This effectively '''replaces''' the vanilla interfaces &amp;lt;code&amp;gt;Container&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;WorldlyContainer&amp;lt;/code&amp;gt;. These&lt;br /&gt;
interfaces are in fact retained only to allow vanilla code to compile and should not be used in mod code. This extends&lt;br /&gt;
to anything that implements those vanilla interfaces, such as &amp;lt;code&amp;gt;RandomizableContainerBlockEntity&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
A default reference implementation for this capability interface is provided in &amp;lt;code&amp;gt;ItemStackHandler&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;tt&amp;gt;IFluidHandler&amp;lt;/tt&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;IFluidHandler&amp;lt;/code&amp;gt; capability refers to the ability for any capability provider to handle and store fluids&lt;br /&gt;
in one or multiple fluid tanks. It is effectively the equivalent in terms of fluids of the &amp;lt;code&amp;gt;IItemHandler&amp;lt;/code&amp;gt;&lt;br /&gt;
capability.&lt;br /&gt;
&lt;br /&gt;
A default reference implementation for this capability interface is provided in &amp;lt;code&amp;gt;TileFluidHandler&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;tt&amp;gt;IFluidHandlerItem&amp;lt;/tt&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;IFluidHandlerItem&amp;lt;/code&amp;gt; capability refers to the ability for an &amp;lt;code&amp;gt;ItemStack&amp;lt;/code&amp;gt; capability provider&lt;br /&gt;
to handle and store fluids in one or multiple fluid tanks. It is basically a specialized version of the&lt;br /&gt;
&amp;lt;code&amp;gt;IFluidHandler&amp;lt;/code&amp;gt; capability that allows &amp;lt;code&amp;gt;ItemStack&amp;lt;/code&amp;gt;s to define a custom container.&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;tt&amp;gt;IEnergyStorage&amp;lt;/tt&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;IEnergyStorage&amp;lt;/code&amp;gt; capability refers to the ability for any capability provider to store, consume, and&lt;br /&gt;
produce energy. This capability is the base capability for what's commonly known in the modded world as Forge Energy (or&lt;br /&gt;
FE), i.e. the energy system most mods use. Its internal design is heavily based on the (now defunct) Redstone Flux&lt;br /&gt;
Energy API, supporting both a push and pull system.&lt;br /&gt;
&lt;br /&gt;
A default reference implementation for this capability interface is provided in &amp;lt;code&amp;gt;EnergyStorage&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;tt&amp;gt;IAnimationStateMachine&amp;lt;/tt&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;IAnimationStateMachine&amp;lt;/code&amp;gt; capability refers to the ability for any capability provider to leverage the Forge Animation State Machine API for animations. This api does not work post 1.12 at the moment.&lt;br /&gt;
&lt;br /&gt;
== Working with Capabilities ==&lt;br /&gt;
&lt;br /&gt;
Both capability providers and users need to be able to provide and access capabilities through a common framework,&lt;br /&gt;
otherwise the ideal of dynamic and mod-agnostic would not really exist. For this reason, both capability providers and&lt;br /&gt;
capability ''accessors'' (which we define as everything that wants to access a capability), also known as '''clients''' or '''users''',&lt;br /&gt;
need to work together and with Forge to ensure that the common interface is used sensibly and correctly by all parties.&lt;br /&gt;
&lt;br /&gt;
=== Obtaining a Capability ===&lt;br /&gt;
&lt;br /&gt;
Before being able to work with a capability, it is necessary to obtain an instance of the &amp;lt;code&amp;gt;Capability&amp;lt;/code&amp;gt; object itself.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;code&amp;gt;Capability&amp;lt;/code&amp;gt; can obtained at any time using &amp;lt;code&amp;gt;CapabilityManager#get&amp;lt;/code&amp;gt;. This takes in an anonymous &amp;lt;code&amp;gt;CapabilityToken&amp;lt;/code&amp;gt; to still allow for a soft dependency system while also keeping hold of any generic information needed. As such, you can always obtain a non-null capability.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public static Capability&amp;lt;IItemHandler&amp;gt; ITEM_HANDLER_CAPABILITY = CapabilityManager.get(new CapabilityToken&amp;lt;&amp;gt;(){});&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above code will let Forge know that the field &amp;lt;code&amp;gt;ITEM_HANDLER_CAPABILITY&amp;lt;/code&amp;gt; should be analogous with the &amp;lt;code&amp;gt;IItemHandler&amp;lt;/code&amp;gt; capability. Note that this does not mean the capability is accessible or registered. To check if it is, call &amp;lt;code&amp;gt;Capability#isRegistered&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
This is, for obvious reasons, redundant, since that capability is also available through&lt;br /&gt;
&amp;lt;code&amp;gt;CapabilityItemHandler&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Exposing a Capability ===&lt;br /&gt;
&lt;br /&gt;
Exposing a capability is a voluntary act by a capability provider that allows the capability to be discovered and&lt;br /&gt;
accessed by users.&lt;br /&gt;
&lt;br /&gt;
To do so, a capability provider needs to juggle a couple more moving pieces to ensure that the capability state remains&lt;br /&gt;
consistent and that the lookup remains fast. It is in fact possible for a capability provider to be asked to provide&lt;br /&gt;
many capabilities many times in the same tick. For this reason, a provider is asked to do the following:&lt;br /&gt;
&lt;br /&gt;
* the &amp;lt;code&amp;gt;LazyOptional&amp;lt;/code&amp;gt;s that get returned '''must be cached''';&lt;br /&gt;
* if a capability changes exposure state (more on this later), all listeners '''must be notified''';&lt;br /&gt;
* if a capability gets invalidated (more on this later), all listeners '''must be notified'''&lt;br /&gt;
* the lookup inside &amp;lt;code&amp;gt;getCapability&amp;lt;/code&amp;gt; must be performed with '''an &amp;lt;code&amp;gt;if&amp;lt;/code&amp;gt;-&amp;lt;code&amp;gt;else&amp;lt;/code&amp;gt; chain''';&lt;br /&gt;
* all unexposed but still present capabilities '''should be available''' if the provider is queried with a &amp;lt;code&amp;gt;null&amp;lt;/code&amp;gt; direction (see ''Accessing a Capability'' for more information);&lt;br /&gt;
* if no capability of a given type is available or accessible, the provider '''must call &amp;lt;code&amp;gt;super&amp;lt;/code&amp;gt; as long as it is possible to do so'''.&lt;br /&gt;
&lt;br /&gt;
Capability providers must also reflect changes in the ''exposure state'' of a capability, meaning that if the&lt;br /&gt;
accessibility of a capability from a certain &amp;lt;code&amp;gt;Direction&amp;lt;/code&amp;gt; changes (refer to&lt;br /&gt;
[[#Accessing a Capability|Accessing a Capability]] for more information), it is the provider's responsibility to trigger&lt;br /&gt;
a state response by invalidating the returned &amp;lt;code&amp;gt;LazyOptional&amp;lt;/code&amp;gt; and caching a new one. This should also be&lt;br /&gt;
performed when a capability gets ''invalidated'', such as when a capability provider gets removed.&lt;br /&gt;
&lt;br /&gt;
With all of the above in mind, part of a capability provider implementation may be similar to the following snippet:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// suppose the presence of a field 'inventory' of type 'IItemHandler'&lt;br /&gt;
&lt;br /&gt;
private final LazyOptional&amp;lt;IItemhandler&amp;gt; inventoryOptional = LazyOptional.of(() -&amp;gt; this.inventory);&lt;br /&gt;
&lt;br /&gt;
@Override&lt;br /&gt;
public &amp;lt;T&amp;gt; LazyOptional&amp;lt;T&amp;gt; getCapability(Capability&amp;lt;T&amp;gt; capability, @Nullable Direction direction) {&lt;br /&gt;
    if (capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY&lt;br /&gt;
            &amp;amp;&amp;amp; (direction == null || direction == Direction.UP || direction == Direction.DOWN)) {&lt;br /&gt;
        return this.inventoryOptional.cast();&lt;br /&gt;
    }&lt;br /&gt;
    return super.getCapability(capability, direction); // See note after snippet&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@Override&lt;br /&gt;
protected void invalidateCaps() {&lt;br /&gt;
    super.invalidateCaps();&lt;br /&gt;
    this.inventoryOptional.invalidate();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This possible implementation of a capability provider exposes an &amp;lt;code&amp;gt;IItemHandler&amp;lt;/code&amp;gt; capability and restricts&lt;br /&gt;
access only to the &amp;lt;code&amp;gt;UP&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;DOWN&amp;lt;/code&amp;gt; directions. If we assume this capability provider is a&lt;br /&gt;
&amp;lt;code&amp;gt;BlockEntity&amp;lt;/code&amp;gt;, then we may also say that the inventory is only accessible from the top and the bottom of the&lt;br /&gt;
block.&lt;br /&gt;
&lt;br /&gt;
Moreover, the capability gets automatically invalidated when the provider gets invalidated. Assuming this is a&lt;br /&gt;
&amp;lt;code&amp;gt;BlockEntity&amp;lt;/code&amp;gt;, this usually happens when the block gets removed from the level or unloaded due to distance.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;super&amp;lt;/code&amp;gt; call at the end of the &amp;lt;code&amp;gt;getCapability&amp;lt;/code&amp;gt; method is extremely important, since it's what&lt;br /&gt;
allows Attaching external Capabilities to capability providers. Nevertheless, it is not always possible to invoke&lt;br /&gt;
&amp;lt;code&amp;gt;super&amp;lt;/code&amp;gt;: in those cases, an empty &amp;lt;code&amp;gt;LazyOptional&amp;lt;/code&amp;gt; should be returned.&lt;br /&gt;
&lt;br /&gt;
=== Attaching a Capability ===&lt;br /&gt;
&lt;br /&gt;
Attaching a Capability is a process by which external agents &amp;quot;modify&amp;quot; a Capability Provider, making it expose additional&lt;br /&gt;
capabilities other than the already available ones.&lt;br /&gt;
&lt;br /&gt;
To do so, the '''attaching agent''' (which means the thing that wants to attach a capability to another provider) must&lt;br /&gt;
listen to the &amp;lt;code&amp;gt;AttachCapabilitiesEvent&amp;amp;lt;T&amp;amp;gt;&amp;lt;/code&amp;gt;. The &amp;lt;code&amp;gt;T&amp;lt;/code&amp;gt; in this case represents the capability&lt;br /&gt;
provider you want to attach the capability to. Note that the type of &amp;lt;code&amp;gt;T&amp;lt;/code&amp;gt; '''must''' be the base type of the&lt;br /&gt;
capability provider, not a subclass. As an example, if you want to attach a capability to a &amp;lt;code&amp;gt;MyBlockEntity&amp;lt;/code&amp;gt;,&lt;br /&gt;
which extends &amp;lt;code&amp;gt;BlockEntity&amp;lt;/code&amp;gt;, you'll have to listen to &amp;lt;code&amp;gt;AttachCapabilitiesEvent&amp;amp;lt;BlockEntity&amp;amp;gt;&amp;lt;/code&amp;gt;,&lt;br /&gt;
'''NOT''' to &amp;lt;code&amp;gt;AttachCapabilitiesEvent&amp;amp;lt;MyBlockEntity&amp;amp;gt;&amp;lt;/code&amp;gt;, since the latter will never fire.&lt;br /&gt;
&lt;br /&gt;
The attaching agent can use the provided methods &amp;lt;code&amp;gt;getObject&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;addCapability&amp;lt;/code&amp;gt;, and &lt;br /&gt;
&amp;lt;code&amp;gt;addListener&amp;lt;/code&amp;gt; to check whether the capability should be attached to the current object and perform the&lt;br /&gt;
desired action.&lt;br /&gt;
&lt;br /&gt;
When attaching a capability, the attaching agent should also provide a name in the form of a&lt;br /&gt;
&amp;lt;code&amp;gt;ResourceLocation&amp;lt;/code&amp;gt;. The name '''must''' be under the attaching agent's namespace, but no restrictions are&lt;br /&gt;
placed on the actual name, as long as it is unique inside the given namespace.&lt;br /&gt;
&lt;br /&gt;
Maybe a little counter-intuitively, the process of attaching does not attach a capability nor a capability interface&lt;br /&gt;
directly. Rather, the attaching agent should create its own implementation of a '''Capability Provider''' and attach it&lt;br /&gt;
via the event. This is done so that the attaching agent can have control over when, how, and where its capabilities are&lt;br /&gt;
exposed, instead of relying on the game itself deciding these parameters. For this reason, all considerations given in&lt;br /&gt;
the [[#Exposing a Capability|Exposing a Capability]] section on how to correctly create a Capability Provider.&lt;br /&gt;
&lt;br /&gt;
With the above in mind, part of an attaching agent may be similar to the following snippet of code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
@SubscribeEvent&lt;br /&gt;
public void onAttachingCapabilities(final AttachCapabilitiesEvent&amp;lt;BlockEntity&amp;gt; event) {&lt;br /&gt;
    if (!(event.getObject() instanceof EnergyBasedBlockEntity)) return;&lt;br /&gt;
&lt;br /&gt;
    EnergyStorage backend = new EnergyStorage(((EnergyBasedBlockEntity) event.getObject()).capacity);&lt;br /&gt;
    LazyOptional&amp;lt;IEnergyStorage&amp;gt; optionalStorage = LazyOptional.of(() -&amp;gt; backend);&lt;br /&gt;
&lt;br /&gt;
    ICapabilityProvider provider = new ICapabilityProvider() {&lt;br /&gt;
        @Override&lt;br /&gt;
        public &amp;lt;T&amp;gt; LazyOptional&amp;lt;T&amp;gt; getCapability(Capability&amp;lt;T&amp;gt; cap, @Nullable Direction direction) {&lt;br /&gt;
            if (cap == CapabilityEnergy.ENERGY) {&lt;br /&gt;
                return optionalStorage.cast();&lt;br /&gt;
            }&lt;br /&gt;
            return LazyOptional.empty();&lt;br /&gt;
        }&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    event.addCapability(new ResourceLocation(&amp;quot;examplemod&amp;quot;, &amp;quot;fe_compatibility&amp;quot;), provider);&lt;br /&gt;
    event.addListener(optionalStorage::invalidate);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This example implementation of an attaching agent attaches a &amp;lt;code&amp;gt;IEnergyStorage&amp;lt;/code&amp;gt; capability to all&lt;br /&gt;
&amp;lt;code&amp;gt;BlockEntity&amp;lt;/code&amp;gt; instance that are a subclass of &amp;lt;code&amp;gt;EnergyBasedBlockEntity&amp;lt;/code&amp;gt;. It also sets up the&lt;br /&gt;
&amp;lt;code&amp;gt;LazyOptional&amp;lt;/code&amp;gt; for invalidation if the parent capability provider gets invalidated.&lt;br /&gt;
&lt;br /&gt;
Note also the call of &amp;lt;code&amp;gt;LazyOptional.empty()&amp;lt;/code&amp;gt; rather than a &amp;lt;code&amp;gt;super&amp;lt;/code&amp;gt;. This is needed because when&lt;br /&gt;
attaching a capability, the parent capability provider isn't known. For this reason, it is necessary to return an empty&lt;br /&gt;
&amp;lt;code&amp;gt;LazyOptional&amp;lt;/code&amp;gt;. The game will then handle automatic merging of the various different providers into a single&lt;br /&gt;
one.&lt;br /&gt;
&lt;br /&gt;
The above example is one of a '''Volatile''' Capability Provider. On the other hand, mods may want to persist their&lt;br /&gt;
data across sessions. In this case, they should attach a '''Persistent''' Capability Provider: this can be done either&lt;br /&gt;
by implementing the &amp;lt;code&amp;gt;INBTSerializable&amp;lt;/code&amp;gt; interface along with &amp;lt;code&amp;gt;ICapabilityProvider&amp;lt;/code&amp;gt; or by&lt;br /&gt;
implementing the &amp;lt;code&amp;gt;ICapabilitySerializable&amp;lt;/code&amp;gt; interface.&lt;br /&gt;
&lt;br /&gt;
The previous example reworked to use a Persistent Capability Provider may be similar to the following snippet:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
@SubscribeEvent&lt;br /&gt;
public void onAttachingCapabilities(final AttachCapabilitiesEvent&amp;lt;BlockEntity&amp;gt; event) {&lt;br /&gt;
    if (!(event.getObject() instanceof EnergyBasedBlockEntity)) return;&lt;br /&gt;
&lt;br /&gt;
    EnergyStorage backend = new EnergyStorage(((EnergyBasedBlockEntity) event.getObject()).capacity);&lt;br /&gt;
    LazyOptional&amp;lt;IEnergyStorage&amp;gt; optionalStorage = LazyOptional.of(() -&amp;gt; backend);&lt;br /&gt;
    Capability&amp;lt;IEnergyStorage&amp;gt; capability = CapabilityEnergy.ENERGY;&lt;br /&gt;
&lt;br /&gt;
    ICapabilityProvider provider = new ICapabilitySerializable&amp;lt;IntTag&amp;gt;() {&lt;br /&gt;
        @Override&lt;br /&gt;
        public &amp;lt;T&amp;gt; LazyOptional&amp;lt;T&amp;gt; getCapability(Capability&amp;lt;T&amp;gt; cap, @Nullable Direction direction) {&lt;br /&gt;
            if (cap == capability) {&lt;br /&gt;
                return optionalStorage.cast();&lt;br /&gt;
            }&lt;br /&gt;
            return LazyOptional.empty();&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        @Override&lt;br /&gt;
        public IntTag serializeNBT() {&lt;br /&gt;
            return backend.serializeNBT();&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        @Override&lt;br /&gt;
        public void deserializeNBT(IntTag tag) {&lt;br /&gt;
            backend.deserializeNBT(tag);&lt;br /&gt;
        }&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    event.addCapabilities(new ResourceLocation(&amp;quot;examplemod&amp;quot;, &amp;quot;fe_compatibility&amp;quot;), provider);&lt;br /&gt;
    event.addListener(optionalStorage::invalidate);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Accessing a Capability ===&lt;br /&gt;
&lt;br /&gt;
Accessing a Capability is the process by which a user is able to '''query''' a Capability Provider for a specific&lt;br /&gt;
instance of a capability.&lt;br /&gt;
&lt;br /&gt;
This is perhaps the second most important part of the entire capability system, since it is what allows cross-mod&lt;br /&gt;
interaction. To obtain an instance of a Capability, the user must first get a hold of the Capability Provider that&lt;br /&gt;
should be queried. This can be done in a variety of ways and is outside the scope of this article. The user should&lt;br /&gt;
then invoke the &amp;lt;code&amp;gt;getCapability&amp;lt;/code&amp;gt; method passing the unique instance of the capability that should be queried&lt;br /&gt;
(see [[#Obtaining a Capability|Obtaining a Capability]] for more information) and the querying &amp;lt;code&amp;gt;Direction&amp;lt;/code&amp;gt;,&lt;br /&gt;
if applicable.&lt;br /&gt;
&lt;br /&gt;
The returned object is a &amp;lt;code&amp;gt;LazyOptional&amp;lt;/code&amp;gt; wrapping the queried Capability, if the capability provider exposes&lt;br /&gt;
it, otherwise it will be empty. The &amp;lt;code&amp;gt;LazyOptional&amp;lt;/code&amp;gt; can be either unwrapped via an &amp;lt;code&amp;gt;orElse&amp;lt;/code&amp;gt; or&lt;br /&gt;
used directly via &amp;lt;code&amp;gt;ifPresent&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
It is '''highly suggested''' to cache the returned &amp;lt;code&amp;gt;LazyOptional&amp;lt;/code&amp;gt; to avoid querying the same provider every&lt;br /&gt;
time, in order to improve performance. The user should thus register itself to the invalidation listener via the&lt;br /&gt;
&amp;lt;code&amp;gt;addListener&amp;lt;/code&amp;gt; method. This ensures that the user will be able to react to the invalidation of the&lt;br /&gt;
&amp;lt;code&amp;gt;LazyOptional&amp;lt;/code&amp;gt; and remove it from the cache.&lt;br /&gt;
&lt;br /&gt;
With the above in mind, part of an user may be similar to the following snippet of code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// note the use of EnumMap, which is much more performant than HashMap for enum keys&lt;br /&gt;
private final Map&amp;lt;Direction, LazyOptional&amp;lt;IEnergyStorage&amp;gt;&amp;gt; cache = new EnumMap&amp;lt;&amp;gt;(Direction.class);&lt;br /&gt;
&lt;br /&gt;
private void sendPowerTo(int power, Direction direction) {&lt;br /&gt;
    LazyOptional&amp;lt;IEnergyStorage&amp;gt; targetCapability = cache.get(direction);&lt;br /&gt;
&lt;br /&gt;
    if (targetCapability == null) {&lt;br /&gt;
        ICapabilityProvider provider = level.getBlockEntity(pos.relative(direction));&lt;br /&gt;
        targetCapability = provider.getCapability(CapabilityEnergy.ENERGY, direction.getOpposite());&lt;br /&gt;
        cache.put(direction, targetCapability);&lt;br /&gt;
        targetCapability.addListener(self -&amp;gt; cache.put(direction, null));&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    targetCapability.ifPresent(storage -&amp;gt; storage.receiveEnergy(power, false));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This example implementation of an user is querying via a &amp;lt;code&amp;gt;BlockEntity&amp;lt;/code&amp;gt; the neighboring capability provider&lt;br /&gt;
for an &amp;lt;code&amp;gt;IEnergyStorage&amp;lt;/code&amp;gt; capability. Before obtaining the provider, the code performs a cache lookup for the&lt;br /&gt;
targeted capability. If the check succeeds, then no lookup is performed; if the check fails, the targeted Capability&lt;br /&gt;
Provider is obtained and queried for the Capability. The obtained &amp;lt;code&amp;gt;LazyOptional&amp;lt;/code&amp;gt; is then cached and a&lt;br /&gt;
listener is attached to it so that the cache would be emptied on invalidation. The code then continues with the&lt;br /&gt;
interaction with the capability, which is outside the scope of this article.&lt;br /&gt;
&lt;br /&gt;
== Creating Custom Capabilities ==&lt;br /&gt;
&lt;br /&gt;
While the various capabilities provided by Forge may satisfy the most common use cases, there is always the chance that&lt;br /&gt;
a mod may require a custom solution. For this reason, Forge provides a way to define a custom Capability.&lt;br /&gt;
&lt;br /&gt;
Defining a custom Capability requires the user to provide one main component: the Capability Interface. Optionally, a &lt;br /&gt;
Capability Implementation and Capability Provider can also be created. In this&lt;br /&gt;
case, the provider will be used as described in [[#Attaching a Capability|Attaching a Capability]]. The various details &lt;br /&gt;
for all these components are described in the respective sections of this article.&lt;br /&gt;
&lt;br /&gt;
In this section, we will refer to the implementation of a &amp;lt;code&amp;gt;MyCapability&amp;lt;/code&amp;gt; capability, that can be used to&lt;br /&gt;
store a single mutable &amp;lt;code&amp;gt;String&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Refer also to [[#Code Examples|Code Examples]] for an example on how the various components may be implemented in a&lt;br /&gt;
real-world scenario.&lt;br /&gt;
&lt;br /&gt;
=== The Capability Interface and the Capability Implementation ===&lt;br /&gt;
&lt;br /&gt;
The Capability Interface is one of the most important parts of a Capability: without it, the Capability effectively does&lt;br /&gt;
not exist. Designing a Capability Interface is exactly like designing any Java interface, so the particular details will&lt;br /&gt;
be glossed over in this section.&lt;br /&gt;
&lt;br /&gt;
The Capability Implementation, on the other hand, is the implementation of the previously defined Capability Interface.&lt;br /&gt;
Usual rules for interface implementations follow. There can be more than one Capability Implementation for each&lt;br /&gt;
capability. &lt;br /&gt;
&lt;br /&gt;
Note that a '''well-formed''' capability implementation should '''not store''' the Capability Provider inside of it: we&lt;br /&gt;
call the capability implementation ''provider-agnostic''. This is not a hard-requirement, though, rather it should act&lt;br /&gt;
more as a guideline. There are in fact certain situations where this cannot be avoided (e.g. attaching a client-synced&lt;br /&gt;
capability to an &amp;lt;code&amp;gt;ItemStack&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Given all of the above information, this may be an example implementation of both a Capability Interface and a&lt;br /&gt;
Capability Implementation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public interface MyCapability {&lt;br /&gt;
    String getValue();&lt;br /&gt;
    void setValue(String value);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class MyCapabilityImplementation implements MyCapability {&lt;br /&gt;
    private String value;&lt;br /&gt;
&lt;br /&gt;
    @Override&lt;br /&gt;
    public String getValue() {&lt;br /&gt;
        return this.value;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    @Override&lt;br /&gt;
    public void setValue(String value) {&lt;br /&gt;
        this.value = value;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that in this case, only a single implementation is provided.&lt;br /&gt;
&lt;br /&gt;
=== The Capability Provider ===&lt;br /&gt;
&lt;br /&gt;
The Capability Provider is an optional component of the capability that allows the Capability to be attached to a&lt;br /&gt;
component. The details on how a Capability Provider should behave have already been discussed in the two previous&lt;br /&gt;
sections [[#Exposing a Capability|Exposing a Capability]] and [[#Attaching a Capability|Attaching a Capability]]: refer&lt;br /&gt;
to those for more information.&lt;br /&gt;
&lt;br /&gt;
=== Tying it All Together ===&lt;br /&gt;
&lt;br /&gt;
Once all components of a Capability have been created, they must be registered so that the game is aware of the&lt;br /&gt;
capability's presence. The registration requires specifying only the Capability Interface.&lt;br /&gt;
&lt;br /&gt;
The registration can be performed by calling the &amp;lt;code&amp;gt;register&amp;lt;/code&amp;gt; method within the &amp;lt;code&amp;gt;RegisterCapabilitiesEvent&amp;lt;/code&amp;gt; which is fired on the &amp;lt;code&amp;gt;MOD&amp;lt;/code&amp;gt; event bus. The&lt;br /&gt;
registration will also automatically inject the created Capability into all relevant fields and methods: refer to&lt;br /&gt;
[[#Obtaining a Capability|Obtaining a Capability]] for more information.&lt;br /&gt;
&lt;br /&gt;
An example of registration can be found in the snippet that follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
@SubscribeEvent&lt;br /&gt;
public void registerCaps(RegisterCapabilitiesEvent event) {&lt;br /&gt;
    event.register(MyCapability.class);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Class Diagram ===&lt;br /&gt;
&lt;br /&gt;
[[File:Custom Capability Class Diagram.svg|800px|thumb|center|Custom Capability Class Diagram]]&lt;br /&gt;
&lt;br /&gt;
In the above diagram the green and red marked areas are classes from Minecraft and Forge respectively. The classes inside the purple area are only needed if you want to [[#Attaching a Capability|Attach a Capability]]. Furthermore this diagram models a persistent provider and its most basic form, for more information on how to create a more complex provider see [[#Custom Capability Providers|Custom Capability Providers]]. To create a volatile provider instead just do not implement &amp;lt;code&amp;gt;INBTSerializable&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Custom Capability Providers ==&lt;br /&gt;
&lt;br /&gt;
Much like custom Capabilities, Forge also allows the creation of custom Capability Providers. The main advantage of this&lt;br /&gt;
is allowing mods to create custom providers for their custom objects, in order to promote not only cross-mod&lt;br /&gt;
compatibility, but also uniformity in the way users may interact with different mod APIs.&lt;br /&gt;
&lt;br /&gt;
This section will only give the basic outline of what is necessary to implement a custom Capability Provider: for more&lt;br /&gt;
in-depth explanation, people are referred to the game code.&lt;br /&gt;
&lt;br /&gt;
By definition, a custom Capability Provider is everything that implements the &amp;lt;code&amp;gt;ICapabilityProvider&amp;lt;/code&amp;gt;&lt;br /&gt;
interface. In this section, though, we will only cover people that may want to replicate the functionality of one of&lt;br /&gt;
the default providers, such as &amp;lt;code&amp;gt;BlockEntity&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;LevelChunk&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The easiest way of doing this is extending the &amp;lt;code&amp;gt;CapabilityProvider&amp;lt;/code&amp;gt; class provided by Forge. This will&lt;br /&gt;
automatically set up an ''agnostic'' Capability Provider. To fully initialize the capability provider, the subclass&lt;br /&gt;
should then invoke the &amp;lt;code&amp;gt;gatherCapabilities&amp;lt;/code&amp;gt; method as the last instruction in its constructor, to ensure that&lt;br /&gt;
the game is able to recollect and attach all capabilities that other mods may want to attach to the capability provider.&lt;br /&gt;
&lt;br /&gt;
== Code Examples ==&lt;br /&gt;
&lt;br /&gt;
* [https://gist.github.com/N1K-x/a17812bac9de4cf064baa789e9ccb96a A Gist showing a quick and dirty example on how to implement a Capability effectively]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Data Storage]]&lt;/div&gt;</summary>
		<author><name>N1K-x</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Capabilities&amp;diff=3097</id>
		<title>Capabilities</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Capabilities&amp;diff=3097"/>
		<updated>2021-12-10T14:32:11Z</updated>

		<summary type="html">&lt;p&gt;N1K-x: Add class diagram to &amp;quot;Creating Custom Capabilities&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Capabilities''' are a Forge system that allows cross-mod interactions by allowing capability ''providers'' to&lt;br /&gt;
dynamically respect contracts and provide specialized behavior without requiring the implementation of many interfaces&lt;br /&gt;
or hard dependencies on mods.&lt;br /&gt;
&lt;br /&gt;
== History ==&lt;br /&gt;
In an ideal world, all that would be needed for a mod to provide the equivalent of a capability would be implementing an&lt;br /&gt;
interface. This is in fact how cross-mod interaction used to work prior to the introduction of capabilities.&lt;br /&gt;
&lt;br /&gt;
The real world, though, is often much more complicated: users wanted to be free to combine mods the way they wanted and&lt;br /&gt;
saw fit, and developers wanted to be able to declare ''soft'' dependencies on other mods, thus reducing the need of&lt;br /&gt;
having a huge mod pack just for testing.&lt;br /&gt;
&lt;br /&gt;
The first approach used by Forge was conditional stripping of interfaces and methods, but this proved to be problematic.&lt;br /&gt;
While the idea works well in theory, in practice the ASM editing of classes relied on complex mechanics and could lead&lt;br /&gt;
to hard to spot bugs.&lt;br /&gt;
&lt;br /&gt;
For this reason, the entire system was redesigned and the concept of '''capabilities''' was born.&lt;br /&gt;
&lt;br /&gt;
== The Concept ==&lt;br /&gt;
A capability allows any capability provider to conditionally expose a certain ability to do something, e.g. accepting&lt;br /&gt;
power or handling items. A capability provider, moreover, can decide to expose a capability only on certain sides,&lt;br /&gt;
allowing for easy interactions with hoppers, cables, etc.&lt;br /&gt;
&lt;br /&gt;
Capabilities may also be added and removed dynamically both from the &amp;quot;owner&amp;quot; of the capability provider and other mods,&lt;br /&gt;
allowing even easier cross-mod interaction. For example, a mod that isn't compatible with Forge Energy could be&lt;br /&gt;
converted into one by dynamically attaching the Forge Energy capability and handling the conversion to a third-party&lt;br /&gt;
energy system without having to alter the original mod.&lt;br /&gt;
&lt;br /&gt;
== Terminology ==&lt;br /&gt;
The high flexibility of the system comes with a cost, though, which is terminology. The following section wants to be a&lt;br /&gt;
dictionary of sorts, defining all the terms that you may come across when dealing with capabilities.&lt;br /&gt;
&lt;br /&gt;
In the rest of this article, we will refer to these terms frequently, so make sure you are familiar with them.&lt;br /&gt;
&lt;br /&gt;
; Capability&lt;br /&gt;
: the ability to perform something. In-code this is represented by the &amp;lt;code&amp;gt;Capability&amp;lt;/code&amp;gt; class.&lt;br /&gt;
; Capability Provider&lt;br /&gt;
: something that is able to support capabilities and provides a mean of accessing them. In-code they are represented by implementations of &amp;lt;code&amp;gt;ICapabilityProvider&amp;lt;/code&amp;gt;. There are multiple kinds of capability providers:&lt;br /&gt;
:; Volatile Provider&lt;br /&gt;
:: a provider that doesn't persist data to disk; once the provider ceases to exist for any number of reasons, all capability data gets deleted.&lt;br /&gt;
:; Persistent Provider&lt;br /&gt;
:: a provider that requires all capabilities to serialize data to disk, in order to persist data even across game restarts. They implement the &amp;lt;code&amp;gt;INBTSerializable&amp;lt;/code&amp;gt; interface.&lt;br /&gt;
:; Agnostic Provider&lt;br /&gt;
:: a provider that isn't neither volatile nor persistent, rather delegates the decision either to the capability directly or to sub-implementations. They also implement the &amp;lt;code&amp;gt;INBTSerializable&amp;lt;/code&amp;gt; interface.&lt;br /&gt;
; Capability Interface&lt;br /&gt;
: the interface that defines the contract of the capability, so what operations the capability exposes.&lt;br /&gt;
; Capability Implementation&lt;br /&gt;
: one of the possibly many implementations of the capability interface, that actually carries out the work.&lt;br /&gt;
&lt;br /&gt;
The wary reader may note that both ''persistent'' and ''agnostic'' providers are represented the same way in code. In&lt;br /&gt;
fact, the only difference between them comes from pure semantics in how their serialization methods are designed. This&lt;br /&gt;
will be further discussed in their respective sections.&lt;br /&gt;
&lt;br /&gt;
Moreover, it is also common to refer to the capability interface as simply the ''capability''. While not strictly&lt;br /&gt;
correct, due to common usage we will also use this convention. So, to refer to the capability interface&lt;br /&gt;
&amp;lt;code&amp;gt;MyCapability&amp;lt;/code&amp;gt;, we will usually talk about the &amp;quot;&amp;lt;code&amp;gt;MyCapability&amp;lt;/code&amp;gt; capability&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Forge-provided Capabilities and Providers ==&lt;br /&gt;
In order to ensure mods can work together seamlessly, Forge provides a set of default capabilities and capability&lt;br /&gt;
providers.&lt;br /&gt;
&lt;br /&gt;
The default capability providers in a Forge environment are: &amp;lt;code&amp;gt;BlockEntity&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Entity&amp;lt;/code&amp;gt;,&lt;br /&gt;
&amp;lt;code&amp;gt;ItemStack&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Level&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;LevelChunk&amp;lt;/code&amp;gt;. These are all agnostic providers, since they don't&lt;br /&gt;
mandate any sort of capability persistency requirements. Rather, it is the job of whoever subclasses these providers to&lt;br /&gt;
deal with either volatile or non-volatile capabilities.&lt;br /&gt;
&lt;br /&gt;
The default capabilities that forge provides are represented by the interfaces &amp;lt;code&amp;gt;IItemHandler&amp;lt;/code&amp;gt;,&lt;br /&gt;
&amp;lt;code&amp;gt;IFluidHandler&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;IFluidHandlerItem&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;IEnergyStorage&amp;lt;/code&amp;gt;, and&lt;br /&gt;
&amp;lt;code&amp;gt;IAnimationStateMachine&amp;lt;/code&amp;gt;. Each one of these capabilities will be discussed in the corresponding section.&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;tt&amp;gt;IItemHandler&amp;lt;/tt&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;IItemHandler&amp;lt;/code&amp;gt; capability refers to the ability for any capability provider to have some sort of internal&lt;br /&gt;
'''inventory''' with a certain number of slots, from which items can be inserted and extracted. It is also possible,&lt;br /&gt;
though, to expose this capability even if no such inventory is present as long as the capability provider can emulate&lt;br /&gt;
its presence (e.g. tools that allow accessing remote inventories).&lt;br /&gt;
&lt;br /&gt;
This effectively '''replaces''' the vanilla interfaces &amp;lt;code&amp;gt;Container&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;WorldlyContainer&amp;lt;/code&amp;gt;. These&lt;br /&gt;
interfaces are in fact retained only to allow vanilla code to compile and should not be used in mod code. This extends&lt;br /&gt;
to anything that implements those vanilla interfaces, such as &amp;lt;code&amp;gt;RandomizableContainerBlockEntity&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
A default reference implementation for this capability interface is provided in &amp;lt;code&amp;gt;ItemStackHandler&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;tt&amp;gt;IFluidHandler&amp;lt;/tt&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;IFluidHandler&amp;lt;/code&amp;gt; capability refers to the ability for any capability provider to handle and store fluids&lt;br /&gt;
in one or multiple fluid tanks. It is effectively the equivalent in terms of fluids of the &amp;lt;code&amp;gt;IItemHandler&amp;lt;/code&amp;gt;&lt;br /&gt;
capability.&lt;br /&gt;
&lt;br /&gt;
A default reference implementation for this capability interface is provided in &amp;lt;code&amp;gt;TileFluidHandler&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;tt&amp;gt;IFluidHandlerItem&amp;lt;/tt&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;IFluidHandlerItem&amp;lt;/code&amp;gt; capability refers to the ability for an &amp;lt;code&amp;gt;ItemStack&amp;lt;/code&amp;gt; capability provider&lt;br /&gt;
to handle and store fluids in one or multiple fluid tanks. It is basically a specialized version of the&lt;br /&gt;
&amp;lt;code&amp;gt;IFluidHandler&amp;lt;/code&amp;gt; capability that allows &amp;lt;code&amp;gt;ItemStack&amp;lt;/code&amp;gt;s to define a custom container.&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;tt&amp;gt;IEnergyStorage&amp;lt;/tt&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;IEnergyStorage&amp;lt;/code&amp;gt; capability refers to the ability for any capability provider to store, consume, and&lt;br /&gt;
produce energy. This capability is the base capability for what's commonly known in the modded world as Forge Energy (or&lt;br /&gt;
FE), i.e. the energy system most mods use. Its internal design is heavily based on the (now defunct) Redstone Flux&lt;br /&gt;
Energy API, supporting both a push and pull system.&lt;br /&gt;
&lt;br /&gt;
A default reference implementation for this capability interface is provided in &amp;lt;code&amp;gt;EnergyStorage&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;tt&amp;gt;IAnimationStateMachine&amp;lt;/tt&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;IAnimationStateMachine&amp;lt;/code&amp;gt; capability refers to the ability for any capability provider to leverage the Forge Animation State Machine API for animations. This api does not work post 1.12 at the moment.&lt;br /&gt;
&lt;br /&gt;
== Working with Capabilities ==&lt;br /&gt;
&lt;br /&gt;
Both capability providers and users need to be able to provide and access capabilities through a common framework,&lt;br /&gt;
otherwise the ideal of dynamic and mod-agnostic would not really exist. For this reason, both capability providers and&lt;br /&gt;
capability ''accessors'' (which we define as everything that wants to access a capability), also known as '''clients''' or '''users''',&lt;br /&gt;
need to work together and with Forge to ensure that the common interface is used sensibly and correctly by all parties.&lt;br /&gt;
&lt;br /&gt;
=== Obtaining a Capability ===&lt;br /&gt;
&lt;br /&gt;
Before being able to work with a capability, it is necessary to obtain an instance of the &amp;lt;code&amp;gt;Capability&amp;lt;/code&amp;gt; object itself.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;code&amp;gt;Capability&amp;lt;/code&amp;gt; can obtained at any time using &amp;lt;code&amp;gt;CapabilityManager#get&amp;lt;/code&amp;gt;. This takes in an anonymous &amp;lt;code&amp;gt;CapabilityToken&amp;lt;/code&amp;gt; to still allow for a soft dependency system while also keeping hold of any generic information needed. As such, you can always obtain a non-null capability.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public static Capability&amp;lt;IItemHandler&amp;gt; ITEM_HANDLER_CAPABILITY = CapabilityManager.get(new CapabilityToken&amp;lt;&amp;gt;(){});&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above code will let Forge know that the field &amp;lt;code&amp;gt;ITEM_HANDLER_CAPABILITY&amp;lt;/code&amp;gt; should be analogous with the &amp;lt;code&amp;gt;IItemHandler&amp;lt;/code&amp;gt; capability. Note that this does not mean the capability is accessible or registered. To check if it is, call &amp;lt;code&amp;gt;Capability#isRegistered&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
This is, for obvious reasons, redundant, since that capability is also available through&lt;br /&gt;
&amp;lt;code&amp;gt;CapabilityItemHandler&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Exposing a Capability ===&lt;br /&gt;
&lt;br /&gt;
Exposing a capability is a voluntary act by a capability provider that allows the capability to be discovered and&lt;br /&gt;
accessed by users.&lt;br /&gt;
&lt;br /&gt;
To do so, a capability provider needs to juggle a couple more moving pieces to ensure that the capability state remains&lt;br /&gt;
consistent and that the lookup remains fast. It is in fact possible for a capability provider to be asked to provide&lt;br /&gt;
many capabilities many times in the same tick. For this reason, a provider is asked to do the following:&lt;br /&gt;
&lt;br /&gt;
* the &amp;lt;code&amp;gt;LazyOptional&amp;lt;/code&amp;gt;s that get returned '''must be cached''';&lt;br /&gt;
* if a capability changes exposure state (more on this later), all listeners '''must be notified''';&lt;br /&gt;
* if a capability gets invalidated (more on this later), all listeners '''must be notified'''&lt;br /&gt;
* the lookup inside &amp;lt;code&amp;gt;getCapability&amp;lt;/code&amp;gt; must be performed with '''an &amp;lt;code&amp;gt;if&amp;lt;/code&amp;gt;-&amp;lt;code&amp;gt;else&amp;lt;/code&amp;gt; chain''';&lt;br /&gt;
* all unexposed but still present capabilities '''should be available''' if the provider is queried with a &amp;lt;code&amp;gt;null&amp;lt;/code&amp;gt; direction (see ''Accessing a Capability'' for more information);&lt;br /&gt;
* if no capability of a given type is available or accessible, the provider '''must call &amp;lt;code&amp;gt;super&amp;lt;/code&amp;gt; as long as it is possible to do so'''.&lt;br /&gt;
&lt;br /&gt;
Capability providers must also reflect changes in the ''exposure state'' of a capability, meaning that if the&lt;br /&gt;
accessibility of a capability from a certain &amp;lt;code&amp;gt;Direction&amp;lt;/code&amp;gt; changes (refer to&lt;br /&gt;
[[#Accessing a Capability|Accessing a Capability]] for more information), it is the provider's responsibility to trigger&lt;br /&gt;
a state response by invalidating the returned &amp;lt;code&amp;gt;LazyOptional&amp;lt;/code&amp;gt; and caching a new one. This should also be&lt;br /&gt;
performed when a capability gets ''invalidated'', such as when a capability provider gets removed.&lt;br /&gt;
&lt;br /&gt;
With all of the above in mind, part of a capability provider implementation may be similar to the following snippet:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// suppose the presence of a field 'inventory' of type 'IItemHandler'&lt;br /&gt;
&lt;br /&gt;
private final LazyOptional&amp;lt;IItemhandler&amp;gt; inventoryOptional = LazyOptional.of(() -&amp;gt; this.inventory);&lt;br /&gt;
&lt;br /&gt;
@Override&lt;br /&gt;
public &amp;lt;T&amp;gt; LazyOptional&amp;lt;T&amp;gt; getCapability(Capability&amp;lt;T&amp;gt; capability, @Nullable Direction direction) {&lt;br /&gt;
    if (capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY&lt;br /&gt;
            &amp;amp;&amp;amp; (direction == null || direction == Direction.UP || direction == Direction.DOWN)) {&lt;br /&gt;
        return this.inventoryOptional.cast();&lt;br /&gt;
    }&lt;br /&gt;
    return super.getCapability(capability, direction); // See note after snippet&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@Override&lt;br /&gt;
protected void invalidateCaps() {&lt;br /&gt;
    super.invalidateCaps();&lt;br /&gt;
    this.inventoryOptional.invalidate();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This possible implementation of a capability provider exposes an &amp;lt;code&amp;gt;IItemHandler&amp;lt;/code&amp;gt; capability and restricts&lt;br /&gt;
access only to the &amp;lt;code&amp;gt;UP&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;DOWN&amp;lt;/code&amp;gt; directions. If we assume this capability provider is a&lt;br /&gt;
&amp;lt;code&amp;gt;BlockEntity&amp;lt;/code&amp;gt;, then we may also say that the inventory is only accessible from the top and the bottom of the&lt;br /&gt;
block.&lt;br /&gt;
&lt;br /&gt;
Moreover, the capability gets automatically invalidated when the provider gets invalidated. Assuming this is a&lt;br /&gt;
&amp;lt;code&amp;gt;BlockEntity&amp;lt;/code&amp;gt;, this usually happens when the block gets removed from the level or unloaded due to distance.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;super&amp;lt;/code&amp;gt; call at the end of the &amp;lt;code&amp;gt;getCapability&amp;lt;/code&amp;gt; method is extremely important, since it's what&lt;br /&gt;
allows Attaching external Capabilities to capability providers. Nevertheless, it is not always possible to invoke&lt;br /&gt;
&amp;lt;code&amp;gt;super&amp;lt;/code&amp;gt;: in those cases, an empty &amp;lt;code&amp;gt;LazyOptional&amp;lt;/code&amp;gt; should be returned.&lt;br /&gt;
&lt;br /&gt;
=== Attaching a Capability ===&lt;br /&gt;
&lt;br /&gt;
Attaching a Capability is a process by which external agents &amp;quot;modify&amp;quot; a Capability Provider, making it expose additional&lt;br /&gt;
capabilities other than the already available ones.&lt;br /&gt;
&lt;br /&gt;
To do so, the '''attaching agent''' (which means the thing that wants to attach a capability to another provider) must&lt;br /&gt;
listen to the &amp;lt;code&amp;gt;AttachCapabilitiesEvent&amp;amp;lt;T&amp;amp;gt;&amp;lt;/code&amp;gt;. The &amp;lt;code&amp;gt;T&amp;lt;/code&amp;gt; in this case represents the capability&lt;br /&gt;
provider you want to attach the capability to. Note that the type of &amp;lt;code&amp;gt;T&amp;lt;/code&amp;gt; '''must''' be the base type of the&lt;br /&gt;
capability provider, not a subclass. As an example, if you want to attach a capability to a &amp;lt;code&amp;gt;MyBlockEntity&amp;lt;/code&amp;gt;,&lt;br /&gt;
which extends &amp;lt;code&amp;gt;BlockEntity&amp;lt;/code&amp;gt;, you'll have to listen to &amp;lt;code&amp;gt;AttachCapabilitiesEvent&amp;amp;lt;BlockEntity&amp;amp;gt;&amp;lt;/code&amp;gt;,&lt;br /&gt;
'''NOT''' to &amp;lt;code&amp;gt;AttachCapabilitiesEvent&amp;amp;lt;MyBlockEntity&amp;amp;gt;&amp;lt;/code&amp;gt;, since the latter will never fire.&lt;br /&gt;
&lt;br /&gt;
The attaching agent can use the provided methods &amp;lt;code&amp;gt;getObject&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;addCapability&amp;lt;/code&amp;gt;, and &lt;br /&gt;
&amp;lt;code&amp;gt;addListener&amp;lt;/code&amp;gt; to check whether the capability should be attached to the current object and perform the&lt;br /&gt;
desired action.&lt;br /&gt;
&lt;br /&gt;
When attaching a capability, the attaching agent should also provide a name in the form of a&lt;br /&gt;
&amp;lt;code&amp;gt;ResourceLocation&amp;lt;/code&amp;gt;. The name '''must''' be under the attaching agent's namespace, but no restrictions are&lt;br /&gt;
placed on the actual name, as long as it is unique inside the given namespace.&lt;br /&gt;
&lt;br /&gt;
Maybe a little counter-intuitively, the process of attaching does not attach a capability nor a capability interface&lt;br /&gt;
directly. Rather, the attaching agent should create its own implementation of a '''Capability Provider''' and attach it&lt;br /&gt;
via the event. This is done so that the attaching agent can have control over when, how, and where its capabilities are&lt;br /&gt;
exposed, instead of relying on the game itself deciding these parameters. For this reason, all considerations given in&lt;br /&gt;
the [[#Exposing a Capability|Exposing a Capability]] section on how to correctly create a Capability Provider.&lt;br /&gt;
&lt;br /&gt;
With the above in mind, part of an attaching agent may be similar to the following snippet of code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
@SubscribeEvent&lt;br /&gt;
public void onAttachingCapabilities(final AttachCapabilitiesEvent&amp;lt;BlockEntity&amp;gt; event) {&lt;br /&gt;
    if (!(event.getObject() instanceof EnergyBasedBlockEntity)) return;&lt;br /&gt;
&lt;br /&gt;
    EnergyStorage backend = new EnergyStorage(((EnergyBasedBlockEntity) event.getObject()).capacity);&lt;br /&gt;
    LazyOptional&amp;lt;IEnergyStorage&amp;gt; optionalStorage = LazyOptional.of(() -&amp;gt; backend);&lt;br /&gt;
&lt;br /&gt;
    ICapabilityProvider provider = new ICapabilityProvider() {&lt;br /&gt;
        @Override&lt;br /&gt;
        public &amp;lt;T&amp;gt; LazyOptional&amp;lt;T&amp;gt; getCapability(Capability&amp;lt;T&amp;gt; cap, @Nullable Direction direction) {&lt;br /&gt;
            if (cap == CapabilityEnergy.ENERGY) {&lt;br /&gt;
                return optionalStorage.cast();&lt;br /&gt;
            }&lt;br /&gt;
            return LazyOptional.empty();&lt;br /&gt;
        }&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    event.addCapability(new ResourceLocation(&amp;quot;examplemod&amp;quot;, &amp;quot;fe_compatibility&amp;quot;), provider);&lt;br /&gt;
    event.addListener(optionalStorage::invalidate);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This example implementation of an attaching agent attaches a &amp;lt;code&amp;gt;IEnergyStorage&amp;lt;/code&amp;gt; capability to all&lt;br /&gt;
&amp;lt;code&amp;gt;BlockEntity&amp;lt;/code&amp;gt; instance that are a subclass of &amp;lt;code&amp;gt;EnergyBasedBlockEntity&amp;lt;/code&amp;gt;. It also sets up the&lt;br /&gt;
&amp;lt;code&amp;gt;LazyOptional&amp;lt;/code&amp;gt; for invalidation if the parent capability provider gets invalidated.&lt;br /&gt;
&lt;br /&gt;
Note also the call of &amp;lt;code&amp;gt;LazyOptional.empty()&amp;lt;/code&amp;gt; rather than a &amp;lt;code&amp;gt;super&amp;lt;/code&amp;gt;. This is needed because when&lt;br /&gt;
attaching a capability, the parent capability provider isn't known. For this reason, it is necessary to return an empty&lt;br /&gt;
&amp;lt;code&amp;gt;LazyOptional&amp;lt;/code&amp;gt;. The game will then handle automatic merging of the various different providers into a single&lt;br /&gt;
one.&lt;br /&gt;
&lt;br /&gt;
The above example is one of a '''Volatile''' Capability Provider. On the other hand, mods may want to persist their&lt;br /&gt;
data across sessions. In this case, they should attach a '''Persistent''' Capability Provider: this can be done either&lt;br /&gt;
by implementing the &amp;lt;code&amp;gt;INBTSerializable&amp;lt;/code&amp;gt; interface along with &amp;lt;code&amp;gt;ICapabilityProvider&amp;lt;/code&amp;gt; or by&lt;br /&gt;
implementing the &amp;lt;code&amp;gt;ICapabilitySerializable&amp;lt;/code&amp;gt; interface.&lt;br /&gt;
&lt;br /&gt;
The previous example reworked to use a Persistent Capability Provider may be similar to the following snippet:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
@SubscribeEvent&lt;br /&gt;
public void onAttachingCapabilities(final AttachCapabilitiesEvent&amp;lt;BlockEntity&amp;gt; event) {&lt;br /&gt;
    if (!(event.getObject() instanceof EnergyBasedBlockEntity)) return;&lt;br /&gt;
&lt;br /&gt;
    EnergyStorage backend = new EnergyStorage(((EnergyBasedBlockEntity) event.getObject()).capacity);&lt;br /&gt;
    LazyOptional&amp;lt;IEnergyStorage&amp;gt; optionalStorage = LazyOptional.of(() -&amp;gt; backend);&lt;br /&gt;
    Capability&amp;lt;IEnergyStorage&amp;gt; capability = CapabilityEnergy.ENERGY;&lt;br /&gt;
&lt;br /&gt;
    ICapabilityProvider provider = new ICapabilitySerializable&amp;lt;IntTag&amp;gt;() {&lt;br /&gt;
        @Override&lt;br /&gt;
        public &amp;lt;T&amp;gt; LazyOptional&amp;lt;T&amp;gt; getCapability(Capability&amp;lt;T&amp;gt; cap, @Nullable Direction direction) {&lt;br /&gt;
            if (cap == capability) {&lt;br /&gt;
                return optionalStorage.cast();&lt;br /&gt;
            }&lt;br /&gt;
            return LazyOptional.empty();&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        @Override&lt;br /&gt;
        public IntTag serializeNBT() {&lt;br /&gt;
            return backend.serializeNBT();&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        @Override&lt;br /&gt;
        public void deserializeNBT(IntTag tag) {&lt;br /&gt;
            backend.deserializeNBT(tag);&lt;br /&gt;
        }&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    event.addCapabilities(new ResourceLocation(&amp;quot;examplemod&amp;quot;, &amp;quot;fe_compatibility&amp;quot;), provider);&lt;br /&gt;
    event.addListener(optionalStorage::invalidate);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Accessing a Capability ===&lt;br /&gt;
&lt;br /&gt;
Accessing a Capability is the process by which a user is able to '''query''' a Capability Provider for a specific&lt;br /&gt;
instance of a capability.&lt;br /&gt;
&lt;br /&gt;
This is perhaps the second most important part of the entire capability system, since it is what allows cross-mod&lt;br /&gt;
interaction. To obtain an instance of a Capability, the user must first get a hold of the Capability Provider that&lt;br /&gt;
should be queried. This can be done in a variety of ways and is outside the scope of this article. The user should&lt;br /&gt;
then invoke the &amp;lt;code&amp;gt;getCapability&amp;lt;/code&amp;gt; method passing the unique instance of the capability that should be queried&lt;br /&gt;
(see [[#Obtaining a Capability|Obtaining a Capability]] for more information) and the querying &amp;lt;code&amp;gt;Direction&amp;lt;/code&amp;gt;,&lt;br /&gt;
if applicable.&lt;br /&gt;
&lt;br /&gt;
The returned object is a &amp;lt;code&amp;gt;LazyOptional&amp;lt;/code&amp;gt; wrapping the queried Capability, if the capability provider exposes&lt;br /&gt;
it, otherwise it will be empty. The &amp;lt;code&amp;gt;LazyOptional&amp;lt;/code&amp;gt; can be either unwrapped via an &amp;lt;code&amp;gt;orElse&amp;lt;/code&amp;gt; or&lt;br /&gt;
used directly via &amp;lt;code&amp;gt;ifPresent&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
It is '''highly suggested''' to cache the returned &amp;lt;code&amp;gt;LazyOptional&amp;lt;/code&amp;gt; to avoid querying the same provider every&lt;br /&gt;
time, in order to improve performance. The user should thus register itself to the invalidation listener via the&lt;br /&gt;
&amp;lt;code&amp;gt;addListener&amp;lt;/code&amp;gt; method. This ensures that the user will be able to react to the invalidation of the&lt;br /&gt;
&amp;lt;code&amp;gt;LazyOptional&amp;lt;/code&amp;gt; and remove it from the cache.&lt;br /&gt;
&lt;br /&gt;
With the above in mind, part of an user may be similar to the following snippet of code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// note the use of EnumMap, which is much more performant than HashMap for enum keys&lt;br /&gt;
private final Map&amp;lt;Direction, LazyOptional&amp;lt;IEnergyStorage&amp;gt;&amp;gt; cache = new EnumMap&amp;lt;&amp;gt;(Direction.class);&lt;br /&gt;
&lt;br /&gt;
private void sendPowerTo(int power, Direction direction) {&lt;br /&gt;
    LazyOptional&amp;lt;IEnergyStorage&amp;gt; targetCapability = cache.get(direction);&lt;br /&gt;
&lt;br /&gt;
    if (targetCapability == null) {&lt;br /&gt;
        ICapabilityProvider provider = level.getBlockEntity(pos.relative(direction));&lt;br /&gt;
        targetCapability = provider.getCapability(CapabilityEnergy.ENERGY, direction.getOpposite());&lt;br /&gt;
        cache.put(direction, targetCapability);&lt;br /&gt;
        targetCapability.addListener(self -&amp;gt; cache.put(direction, null));&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    targetCapability.ifPresent(storage -&amp;gt; storage.receiveEnergy(power, false));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This example implementation of an user is querying via a &amp;lt;code&amp;gt;BlockEntity&amp;lt;/code&amp;gt; the neighboring capability provider&lt;br /&gt;
for an &amp;lt;code&amp;gt;IEnergyStorage&amp;lt;/code&amp;gt; capability. Before obtaining the provider, the code performs a cache lookup for the&lt;br /&gt;
targeted capability. If the check succeeds, then no lookup is performed; if the check fails, the targeted Capability&lt;br /&gt;
Provider is obtained and queried for the Capability. The obtained &amp;lt;code&amp;gt;LazyOptional&amp;lt;/code&amp;gt; is then cached and a&lt;br /&gt;
listener is attached to it so that the cache would be emptied on invalidation. The code then continues with the&lt;br /&gt;
interaction with the capability, which is outside the scope of this article.&lt;br /&gt;
&lt;br /&gt;
== Creating Custom Capabilities ==&lt;br /&gt;
&lt;br /&gt;
While the various capabilities provided by Forge may satisfy the most common use cases, there is always the chance that&lt;br /&gt;
a mod may require a custom solution. For this reason, Forge provides a way to define a custom Capability.&lt;br /&gt;
&lt;br /&gt;
Defining a custom Capability requires the user to provide one main component: the Capability Interface. Optionally, a &lt;br /&gt;
Capability Implementation and Capability Provider can also be created. In this&lt;br /&gt;
case, the provider will be used as described in [[#Attaching a Capability|Attaching a Capability]]. The various details &lt;br /&gt;
for all these components are described in the respective sections of this article.&lt;br /&gt;
&lt;br /&gt;
In this section, we will refer to the implementation of a &amp;lt;code&amp;gt;MyCapability&amp;lt;/code&amp;gt; capability, that can be used to&lt;br /&gt;
store a single mutable &amp;lt;code&amp;gt;String&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Refer also to [[#Code Examples|Code Examples]] for an example on how the various components may be implemented in a&lt;br /&gt;
real-world scenario.&lt;br /&gt;
&lt;br /&gt;
=== The Capability Interface and the Capability Implementation ===&lt;br /&gt;
&lt;br /&gt;
The Capability Interface is one of the most important parts of a Capability: without it, the Capability effectively does&lt;br /&gt;
not exist. Designing a Capability Interface is exactly like designing any Java interface, so the particular details will&lt;br /&gt;
be glossed over in this section.&lt;br /&gt;
&lt;br /&gt;
The Capability Implementation, on the other hand, is the implementation of the previously defined Capability Interface.&lt;br /&gt;
Usual rules for interface implementations follow. There can be more than one Capability Implementation for each&lt;br /&gt;
capability. &lt;br /&gt;
&lt;br /&gt;
Note that a '''well-formed''' capability implementation should '''not store''' the Capability Provider inside of it: we&lt;br /&gt;
call the capability implementation ''provider-agnostic''. This is not a hard-requirement, though, rather it should act&lt;br /&gt;
more as a guideline. There are in fact certain situations where this cannot be avoided (e.g. attaching a client-synced&lt;br /&gt;
capability to an &amp;lt;code&amp;gt;ItemStack&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Given all of the above information, this may be an example implementation of both a Capability Interface and a&lt;br /&gt;
Capability Implementation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public interface MyCapability {&lt;br /&gt;
    String getValue();&lt;br /&gt;
    void setValue(String value);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class MyCapabilityImplementation implements MyCapability {&lt;br /&gt;
    private String value;&lt;br /&gt;
&lt;br /&gt;
    @Override&lt;br /&gt;
    public String getValue() {&lt;br /&gt;
        return this.value;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    @Override&lt;br /&gt;
    public void setValue(String value) {&lt;br /&gt;
        this.value = value;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that in this case, only a single implementation is provided.&lt;br /&gt;
&lt;br /&gt;
=== The Capability Provider ===&lt;br /&gt;
&lt;br /&gt;
The Capability Provider is an optional component of the capability that allows the Capability to be attached to a&lt;br /&gt;
component. The details on how a Capability Provider should behave have already been discussed in the two previous&lt;br /&gt;
sections [[#Exposing a Capability|Exposing a Capability]] and [[#Attaching a Capability|Attaching a Capability]]: refer&lt;br /&gt;
to those for more information.&lt;br /&gt;
&lt;br /&gt;
=== Tying it All Together ===&lt;br /&gt;
&lt;br /&gt;
Once all components of a Capability have been created, they must be registered so that the game is aware of the&lt;br /&gt;
capability's presence. The registration requires specifying only the Capability Interface.&lt;br /&gt;
&lt;br /&gt;
The registration can be performed by calling the &amp;lt;code&amp;gt;register&amp;lt;/code&amp;gt; method within the &amp;lt;code&amp;gt;RegisterCapabilitiesEvent&amp;lt;/code&amp;gt; which is fired on the &amp;lt;code&amp;gt;MOD&amp;lt;/code&amp;gt; event bus. The&lt;br /&gt;
registration will also automatically inject the created Capability into all relevant fields and methods: refer to&lt;br /&gt;
[[#Obtaining a Capability|Obtaining a Capability]] for more information.&lt;br /&gt;
&lt;br /&gt;
An example of registration can be found in the snippet that follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
@SubscribeEvent&lt;br /&gt;
public void registerCaps(RegisterCapabilitiesEvent event) {&lt;br /&gt;
    event.register(MyCapability.class);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Class Diagram ===&lt;br /&gt;
&lt;br /&gt;
[[File:Custom Capability Class Diagram.svg|800px|thumb|center|Custom Capability Class Diagram]]&lt;br /&gt;
&lt;br /&gt;
In the above diagram the green and red marked areas are classes from Minecraft and Forge respectively. The classes inside the purple area are only needed if you want to [[#Attaching a Capability|Attach a Capability]]. Furthermore this diagram models a persistent provider and its most basic form, for more information on how to create a more complex provider see [[#Custom Capability Providers|Custom Capability Providers]]. To create a volatile provider instead just do not implement &amp;lt;code&amp;gt;INBTSerializable&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Custom Capability Providers ==&lt;br /&gt;
&lt;br /&gt;
Much like custom Capabilities, Forge also allows the creation of custom Capability Providers. The main advantage of this&lt;br /&gt;
is allowing mods to create custom providers for their custom objects, in order to promote not only cross-mod&lt;br /&gt;
compatibility, but also uniformity in the way users may interact with different mod APIs.&lt;br /&gt;
&lt;br /&gt;
This section will only give the basic outline of what is necessary to implement a custom Capability Provider: for more&lt;br /&gt;
in-depth explanation, people are referred to the game code.&lt;br /&gt;
&lt;br /&gt;
By definition, a custom Capability Provider is everything that implements the &amp;lt;code&amp;gt;ICapabilityProvider&amp;lt;/code&amp;gt;&lt;br /&gt;
interface. In this section, though, we will only cover people that may want to replicate the functionality of one of&lt;br /&gt;
the default providers, such as &amp;lt;code&amp;gt;BlockEntity&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;LevelChunk&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The easiest way of doing this is extending the &amp;lt;code&amp;gt;CapabilityProvider&amp;lt;/code&amp;gt; class provided by Forge. This will&lt;br /&gt;
automatically set up an ''agnostic'' Capability Provider. To fully initialize the capability provider, the subclass&lt;br /&gt;
should then invoke the &amp;lt;code&amp;gt;gatherCapabilities&amp;lt;/code&amp;gt; method as the last instruction in its constructor, to ensure that&lt;br /&gt;
the game is able to recollect and attach all capabilities that other mods may want to attach to the capability provider.&lt;br /&gt;
&lt;br /&gt;
== Code Examples ==&lt;br /&gt;
&lt;br /&gt;
* [https://gist.github.com/TheSilkMiner/5cc92ba573e7bdd871dfdbffdd5c2806 A Gist showing a quick and dirty example on how to implement a Capability effectively]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Data Storage]]&lt;/div&gt;</summary>
		<author><name>N1K-x</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=File:Custom_Capability_Class_Diagram.svg&amp;diff=3096</id>
		<title>File:Custom Capability Class Diagram.svg</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=File:Custom_Capability_Class_Diagram.svg&amp;diff=3096"/>
		<updated>2021-12-10T14:14:17Z</updated>

		<summary type="html">&lt;p&gt;N1K-x: N1K-x uploaded a new version of File:Custom Capability Class Diagram.svg&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;A UML Class Diagram showing the essential parts for creating a custom capability.&lt;/div&gt;</summary>
		<author><name>N1K-x</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=File:Custom_Capability_Class_Diagram.svg&amp;diff=3095</id>
		<title>File:Custom Capability Class Diagram.svg</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=File:Custom_Capability_Class_Diagram.svg&amp;diff=3095"/>
		<updated>2021-12-10T14:00:32Z</updated>

		<summary type="html">&lt;p&gt;N1K-x: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;A UML Class Diagram showing the essential parts for creating a custom capability.&lt;/div&gt;</summary>
		<author><name>N1K-x</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Getting_Started&amp;diff=2952</id>
		<title>Getting Started</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Getting_Started&amp;diff=2952"/>
		<updated>2021-09-07T13:51:31Z</updated>

		<summary type="html">&lt;p&gt;N1K-x: Update some links (mainly gradle since we no longer use a snapshot version)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Minecraft Forge''' is a modding framework, designed to allow different mods to load and work together to be compatible. Through the years, there has been many changes in the Forge tooling to make working with mods as seamless as possible. It is now easier than ever to start making your own mod.&lt;br /&gt;
&lt;br /&gt;
== The Mod Development Kit ==&lt;br /&gt;
The '''Mod Development Kit''' or '''MDK''' is a downloadable archive that contains the basic skeleton for starting a new mod. It contains the following files and folders:&lt;br /&gt;
&lt;br /&gt;
{{Tree list}}&lt;br /&gt;
* '''The Mod Development Kit'''&lt;br /&gt;
** &amp;lt;code&amp;gt;gradle/wrapper/&amp;lt;/code&amp;gt; - The folder containing the [https://docs.gradle.org/7.2/userguide/gradle_wrapper.html Gradle wrapper]'', Forge uses Version '''7.2'''''&lt;br /&gt;
** &amp;lt;code&amp;gt;src&amp;lt;/code&amp;gt; - The sources folder&lt;br /&gt;
*** &amp;lt;code&amp;gt;main&amp;lt;/code&amp;gt; - The &amp;lt;code&amp;gt;main&amp;lt;/code&amp;gt; source set&lt;br /&gt;
**** &amp;lt;code&amp;gt;java&amp;lt;/code&amp;gt; - The java sources for the &amp;lt;code&amp;gt;main&amp;lt;/code&amp;gt; source set&lt;br /&gt;
***** ...&lt;br /&gt;
**** &amp;lt;code&amp;gt;resources&amp;lt;/code&amp;gt; - The resources for the &amp;lt;code&amp;gt;main&amp;lt;/code&amp;gt; source set&lt;br /&gt;
***** &amp;lt;code&amp;gt;META-INF&amp;lt;/code&amp;gt; - The folder for '''meta'''data '''inf'''ormation files&amp;lt;ref&amp;gt;[https://stackoverflow.com/a/6075320/14416954 StackOverflow answer]: ''... Basically, if it was stored in META-INF, it was Meta-data Information...''&amp;lt;/ref&amp;gt;&lt;br /&gt;
****** &amp;lt;code&amp;gt;mods.toml&amp;lt;/code&amp;gt; - The [[Mods.toml file|&amp;lt;tt&amp;gt;mods.toml&amp;lt;/tt&amp;gt; file]], where mods are declared&lt;br /&gt;
***** &amp;lt;code&amp;gt;pack.mcmeta&amp;lt;/code&amp;gt; - File used by Minecraft to [[mc:Data Pack#pack.mcmeta|identify data and resource packs]]&lt;br /&gt;
** &amp;lt;code&amp;gt;.gitattributes&amp;lt;/code&amp;gt; - Used by [[wikipedia:Git|Git]] for specifying attributes for files&amp;lt;ref&amp;gt;[https://git-scm.com/docs/gitattributes Official git documentation on &amp;lt;tt&amp;gt;.gitattributes&amp;lt;/tt&amp;gt;]&amp;lt;/ref&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;.gitignore&amp;lt;/code&amp;gt; - Used by Git for specifying intentionally untracked/ignored files&amp;lt;ref&amp;gt;[https://git-scm.com/docs/gitignore Official git documentation on &amp;lt;tt&amp;gt;.gitignore&amp;lt;/tt&amp;gt;]&amp;lt;/ref&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;build.gradle&amp;lt;/code&amp;gt; - The Gradle buildscript, which defines the project and tasks&amp;lt;ref&amp;gt;[https://docs.gradle.org/7.2/userguide/tutorial_using_tasks.html Gradle User Guide for 7.2: ''Build Script Basics'']&amp;lt;/ref&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;changelog.txt&amp;lt;/code&amp;gt; - The Forge version changelog&lt;br /&gt;
** &amp;lt;code&amp;gt;CREDITS.txt&amp;lt;/code&amp;gt; - Forge's credits/''thank you'' file&lt;br /&gt;
** &amp;lt;code&amp;gt;gradle.properties&amp;lt;/code&amp;gt; - The Gradle properties file, for defining additional variables and options&amp;lt;ref&amp;gt;[https://docs.gradle.org/7.2/userguide/build_environment.html#sec:gradle_configuration_properties Gradle User Guide for 7.2: ''Build Environment § Gradle properties'']&amp;lt;/ref&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;gradlew&amp;lt;/code&amp;gt; - The *nix shell file for executing the Gradle wrapper&lt;br /&gt;
** &amp;lt;code&amp;gt;gradlew.bat&amp;lt;/code&amp;gt; - The Windows batch file for executing the Gradle wrapper&lt;br /&gt;
** &amp;lt;code&amp;gt;LICENSE.txt&amp;lt;/code&amp;gt; - File containing the licensing information for Forge and libraries&lt;br /&gt;
** &amp;lt;code&amp;gt;README.txt&amp;lt;/code&amp;gt; - Readme file with the basic setup instructions&lt;br /&gt;
{{Tree list/end}}&lt;br /&gt;
&lt;br /&gt;
== Basic MDK Setup ==&lt;br /&gt;
# Download the MDK from the [https://files.minecraftforge.net/ official Minecraft Forge download site] and extract the MDK into an empty folder.&lt;br /&gt;
# Open your IDE of choice, and import the project as a Gradle project.&lt;br /&gt;
#* For '''Eclipse''': &amp;lt;tt&amp;gt;File &amp;gt; Import &amp;gt; Gradle &amp;gt; Existing Gradle Project&amp;lt;/tt&amp;gt;, select the folder for the &amp;lt;tt&amp;gt;Project root directory&amp;lt;/tt&amp;gt;, click &amp;lt;tt&amp;gt;Finish&amp;lt;/tt&amp;gt;&lt;br /&gt;
#* For '''IntelliJ IDEA''': &amp;lt;tt&amp;gt;File &amp;gt; Open&amp;lt;/tt&amp;gt;, select and open the folder, select the &amp;lt;tt&amp;gt;build.gradle&amp;lt;/tt&amp;gt; file, click &amp;lt;tt&amp;gt;OK&amp;lt;/tt&amp;gt;, click &amp;lt;tt&amp;gt;Open as Project&amp;lt;/tt&amp;gt;&lt;br /&gt;
# Wait for the setup process to complete and the Minecraft sources are decompiled.&lt;br /&gt;
# Generate the run configurations for your IDE using the appropriate Gradle task. &amp;lt;br&amp;gt;These tasks can be run on the command line using ''(Windows)'' &amp;lt;code&amp;gt;gradlew gen***Runs&amp;lt;/code&amp;gt; or ''(*nix)'' &amp;lt;code&amp;gt;./gradlew gen***Runs&amp;lt;/code&amp;gt;.&lt;br /&gt;
#* For ''Eclipse'': the task is &amp;lt;code&amp;gt;genEclipseRuns&amp;lt;/code&amp;gt;; to run in the IDE directly, open the &amp;lt;tt&amp;gt;Gradle Tasks&amp;lt;/tt&amp;gt; tab on the bottom panel, ''wait until the tasks have loaded'' then expand the folder, expand the &amp;lt;tt&amp;gt;fg_runs&amp;lt;/tt&amp;gt; folder, then double-click &amp;lt;tt&amp;gt;genEclipseRuns&amp;lt;/tt&amp;gt;.&lt;br /&gt;
#* For ''IntelliJ IDEA'': the task is &amp;lt;code&amp;gt;genIntellijRuns&amp;lt;/code&amp;gt;; to run in the IDE directly, open the &amp;lt;tt&amp;gt;Gradle&amp;lt;/tt&amp;gt; on the right, expand the project folder, double-click &amp;lt;tt&amp;gt;Tasks &amp;gt; fg_runs &amp;gt; genIntellijRuns&amp;lt;/tt&amp;gt;.&lt;br /&gt;
#* For ''Visual Studio Code'': the task is &amp;lt;code&amp;gt;genVSCodeRuns&amp;lt;/code&amp;gt;; the Java plugin and Gradle tasks plugin should both be installed for smoother integration.&lt;br /&gt;
&lt;br /&gt;
{{Tip|The most popular IDEs used by Forge and mod developers are [https://www.eclipse.org/eclipseide/ Eclipse] and [https://www.jetbrains.com/idea/ IntelliJ IDEA]. While Visual Studio Code has a run generation task, because of its relative unpopularity as an IDE for Minecraft modding, the user will have to self-diagnose any issues that may arise from their use of it.}}&lt;br /&gt;
&lt;br /&gt;
== Customizing the MDK ==&lt;br /&gt;
The MDK provides default values for the buildscript and &amp;lt;tt&amp;gt;mods.toml&amp;lt;/tt&amp;gt; file. These values should be replaced with your own mod's information.&lt;br /&gt;
&lt;br /&gt;
All edits should be done below the &amp;lt;code&amp;gt;apply plugin: 'net.minecraftforge.gradle'&amp;lt;/code&amp;gt; line. The lines above it are required for the Forge MDK to work correctly, and should not be modified without proper knowledge.&lt;br /&gt;
* All references to &amp;lt;code&amp;gt;examplemod&amp;lt;/code&amp;gt; in the buildscript should be replaced with your modid.&lt;br /&gt;
** Use your IDE's find-and-replace function to quickly replace these values.&lt;br /&gt;
** Pick a unique and memorable modid. The modid must be between 2 and 64 characters, and must consist of lowercase letters, numbers, underscores (&amp;lt;code&amp;gt;_&amp;lt;/code&amp;gt;) and hyphens (&amp;lt;code&amp;gt;-&amp;lt;/code&amp;gt;). The recommendation is to avoid using acronyms and abbreviations.&lt;br /&gt;
* Change the &amp;lt;code&amp;gt;archivesBaseName&amp;lt;/code&amp;gt; variable to your modid. This is used as the base name for the JAR file when you build your mod, and as the &amp;lt;tt&amp;gt;artifactId&amp;lt;/tt&amp;gt; of your mod's [https://maven.apache.org/pom.html#Maven_Coordinates maven coordinates].&lt;br /&gt;
* Change the &amp;lt;code&amp;gt;group&amp;lt;/code&amp;gt; to your [[Proper Mod Structuring#Packaging|unique root java package]]. This is used as the &amp;lt;tt&amp;gt;groupId&amp;lt;/tt&amp;gt; of your mod's maven coordinates.&lt;br /&gt;
* In the &amp;lt;code&amp;gt;jar&amp;lt;/code&amp;gt; task, change the values of the &amp;lt;code&amp;gt;Specification-Vendor&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;Implementation-Vendor&amp;lt;/code&amp;gt; keys to your username/brand name or other form of identification.&lt;br /&gt;
* ''Optional suggestion: '' Change the &amp;lt;code&amp;gt;version&amp;lt;/code&amp;gt; variable to have a 0 as the major version (ex. &amp;lt;code&amp;gt;'0.1'&amp;lt;/code&amp;gt;. This is to follow [[Semantic Versioning#During Development|semantic versioning guidelines]] for versions in active development.&lt;br /&gt;
&lt;br /&gt;
== Building and Testing ==&lt;br /&gt;
You can test your mod in the development environment using either your IDE's run configurations and built-in debugging utilities, or by running the &amp;lt;code&amp;gt;run*&amp;lt;/code&amp;gt; task as defined by the buildscript's run configurations.&lt;br /&gt;
&lt;br /&gt;
There are three default run configurations with the MDK:&lt;br /&gt;
* &amp;lt;code&amp;gt;runClient&amp;lt;/code&amp;gt;, for starting the client.&lt;br /&gt;
* &amp;lt;code&amp;gt;runServer&amp;lt;/code&amp;gt;, for starting the dedicated server. ''You will need to accept the EULA through the &amp;lt;tt&amp;gt;eula.txt&amp;lt;/tt&amp;gt; after running the server for the first time.''&lt;br /&gt;
* &amp;lt;code&amp;gt;runData&amp;lt;/code&amp;gt;, for starting the client in [[Datageneration|data generation]] mode.&lt;br /&gt;
&lt;br /&gt;
{{Tip|Always test your mod in both the client and the dedicated server, even if you are making a one-sided mod. Mods should not crash when running on both sides, and one-sided mods should not crash if they run on the wrong side.}}&lt;br /&gt;
&lt;br /&gt;
You can build your mod's final JAR using the &amp;lt;code&amp;gt;build&amp;lt;/code&amp;gt; task. The resulting JAR will be located in the &amp;lt;code&amp;gt;build/libs&amp;lt;/code&amp;gt; folder under your project directory.&lt;br /&gt;
&lt;br /&gt;
[[Category:Getting Started]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Beginner Topics]]&lt;/div&gt;</summary>
		<author><name>N1K-x</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Mods.toml&amp;diff=2944</id>
		<title>Mods.toml</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Mods.toml&amp;diff=2944"/>
		<updated>2021-09-01T11:18:50Z</updated>

		<summary type="html">&lt;p&gt;N1K-x: Fix description description&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Under construction}}&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;mods.toml&amp;lt;/code&amp;gt; file is read by the mod loader to determine what mods are packaged into your JAR file, and what information to display to the user in the Mods listing screen (accessible by pressing the &amp;quot;Mods&amp;quot; button on the main menu of the game). &lt;br /&gt;
&lt;br /&gt;
The file is formatted in [https://toml.io/en/ Tom's Obvious Minimal Language], or TOML for short. The example &amp;lt;code&amp;gt;mods.toml&amp;lt;/code&amp;gt; file in the MDK provides comments explaining the contents of the file. It should be stored under the &amp;lt;code&amp;gt;META-INF&amp;lt;/code&amp;gt; folder in your resources directory (&amp;lt;code&amp;gt;src/main/resources/META-INF/mods.toml&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Example &amp;lt;code&amp;gt;mods.toml&amp;lt;/code&amp;gt; file:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;TOML&amp;quot;&amp;gt;&lt;br /&gt;
modLoader=&amp;quot;javafml&amp;quot;&lt;br /&gt;
# Forge for 1.17.1 is version 37&lt;br /&gt;
loaderVersion=&amp;quot;[37,)&amp;quot;&lt;br /&gt;
license=&amp;quot;All rights reserved&amp;quot;&lt;br /&gt;
issueTrackerURL=&amp;quot;github.com/MinecraftForge/MinecraftForge/issues&amp;quot;&lt;br /&gt;
showAsResourcePack=false&lt;br /&gt;
&lt;br /&gt;
[[mods]]&lt;br /&gt;
    modId=&amp;quot;examplemod&amp;quot;&lt;br /&gt;
    version=&amp;quot;1.0.0.0&amp;quot;&lt;br /&gt;
    displayName=&amp;quot;Example Mod&amp;quot;&lt;br /&gt;
    updateJSONURL=&amp;quot;minecraftforge.net/versions.json&amp;quot;&lt;br /&gt;
    displayURL=&amp;quot;minecraftforge.net&amp;quot;&lt;br /&gt;
    logoFile=&amp;quot;logo.png&amp;quot;&lt;br /&gt;
    credits=&amp;quot;I'd like to thank my mother and father.&amp;quot;&lt;br /&gt;
    authors=&amp;quot;Author&amp;quot;&lt;br /&gt;
    description='''&lt;br /&gt;
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.&lt;br /&gt;
    '''&lt;br /&gt;
&lt;br /&gt;
[[dependencies.examplemod]]&lt;br /&gt;
    modId=&amp;quot;forge&amp;quot;&lt;br /&gt;
    mandatory=true&lt;br /&gt;
    versionRange=&amp;quot;[37,)&amp;quot;&lt;br /&gt;
    ordering=&amp;quot;NONE&amp;quot;&lt;br /&gt;
    side=&amp;quot;BOTH&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[[dependencies.examplemod]]&lt;br /&gt;
    modId=&amp;quot;minecraft&amp;quot;&lt;br /&gt;
    mandatory=true&lt;br /&gt;
    versionRange=&amp;quot;[1.17.1,1.18)&amp;quot;&lt;br /&gt;
    ordering=&amp;quot;NONE&amp;quot;&lt;br /&gt;
    side=&amp;quot;BOTH&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the &amp;lt;code&amp;gt;version&amp;lt;/code&amp;gt; is specified as&amp;lt;code&amp;gt;${file.jarVersion}&amp;lt;/code&amp;gt;, Forge will replace the string with the 'Implementation Version' specified in the jar manifest at runtime. Since the userdev environment has no jar manifest to pull from, it will be &amp;lt;code&amp;gt;NONE&amp;lt;/code&amp;gt; instead. As such, it is usually recommended to leave this field alone.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;mods.toml&amp;lt;/code&amp;gt; is split into three parts: the non-mod-specific properties, which are linked to the mod file; the mod properties, with a section for each mod; and dependency configurations, with a section for each mod's dependencies. Here is a table of attributes that may be given to a mod, where &amp;lt;code&amp;gt;mandatory&amp;lt;/code&amp;gt; means there is no default and the absence of the property causes an error.&lt;br /&gt;
&lt;br /&gt;
===Non-Mod-Specific Properties===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!|Property&lt;br /&gt;
!|Type&lt;br /&gt;
!|Defaults&lt;br /&gt;
!|Description&lt;br /&gt;
!|Example&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;modLoader&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|'''mandatory'''&lt;br /&gt;
|The language loader for the mod. Used to specify an alternative language for the mod, such as Kotlin, if one exists. The Forge-provided Java loader is &amp;lt;code&amp;gt;javafml&amp;lt;/code&amp;gt;.&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;javafml&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;loaderVersion&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|'''mandatory'''&lt;br /&gt;
|The acceptable version range of the language loader, expressed as a [https://maven.apache.org/enforcer/enforcer-rules/versionRanges.html Maven version spec]. For the Forge-provided Java loader, the version is the major version of the Forge version.&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;[37,)&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;license&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|'''mandatory'''&lt;br /&gt;
|The license for the mod(s) in this JAR. This string may be any valid string, but it is suggested to set the value to be the name of your license, and/or a link to that license.&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;GNU GPL v3, https://www.gnu.org/licenses/gpl-3.0.en.html&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;showAsResourcePack&amp;lt;/code&amp;gt;&lt;br /&gt;
|boolean&lt;br /&gt;
|&amp;lt;code&amp;gt;false&amp;lt;/code&amp;gt;&lt;br /&gt;
|Whether to display this mod's resources as a separate option in the resource pack menu. If disabled, the mod's resources will be rolled into the &amp;quot;Mod resources&amp;quot; pack.&lt;br /&gt;
|&amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;properties&amp;lt;/code&amp;gt;&lt;br /&gt;
|table&lt;br /&gt;
|&amp;lt;code&amp;gt;{}&amp;lt;/code&amp;gt;&lt;br /&gt;
|A table of custom substitution properties. This is used by &amp;lt;code&amp;gt;StringSubstitutor&amp;lt;/code&amp;gt; to replace values, using &amp;lt;code&amp;gt;${file.*}&amp;lt;/code&amp;gt;.&lt;br /&gt;
|&amp;lt;code&amp;gt;{ &amp;quot;thingy&amp;quot; = 1 }&amp;lt;/code&amp;gt;, used in &amp;lt;code&amp;gt;${file.thingy}&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;issueTrackerURL&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|''nothing''&lt;br /&gt;
|A URL for an issues tracker. This should never be a blank string, as that will cause an error.&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&amp;quot;http://my.issue.tracker/&amp;quot;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Mod Properties===&lt;br /&gt;
A mod entry is defined by a new section starting with a &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;[[mods]]&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; header (In TOML, the &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;[[mods]]&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; defines an [https://toml.io/en/v1.0.0-rc.2#array-of-tables array of tables]). All properties from that line until the next header will become the properties for that mod.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!|Property&lt;br /&gt;
!|Type&lt;br /&gt;
!|Defaults&lt;br /&gt;
!|Description&lt;br /&gt;
!|Example&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;modId&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|'''mandatory'''&lt;br /&gt;
|The mod's identifier (modid). This must match the following regex: &amp;lt;code&amp;gt;^[a-z][a-z0-9_-]{1,63}$&amp;lt;/code&amp;gt; (starts with a lowercase letter; other characters must be a lowercase letter, number, underscore or hyphen; must be 2-64 characters long).&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;examplemod&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;namespace&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|value of &amp;lt;code&amp;gt;modId&amp;lt;/code&amp;gt;&lt;br /&gt;
|An override namespace. Currently, there is no use for this property&lt;br /&gt;
|&amp;lt;code&amp;gt;example&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;version&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;1&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|The mod's version, ideally conforming to [[Semantic Versioning|semantic versioning]]. The default value in the MDK for this is &amp;lt;code&amp;gt;${file.jarVersion}&amp;lt;/code&amp;gt;, which is replaced at runtime with the &amp;lt;code&amp;gt;Implementation-Version&amp;lt;/code&amp;gt; found in the jar's manifest file.&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;0.2.4-beta1&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;displayName&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|value of &amp;lt;code&amp;gt;modId&amp;lt;/code&amp;gt;&lt;br /&gt;
|The display name of the mod, for use in the Mods listing screen&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;Example Mod&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;description&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;MISSING DESCRIPTION&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|The description of the mod, for use in the Mods listing screen. It's recommended to use a multiline string (surrounded by &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;'''&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;)&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;Adds things and stuff. &amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;logoFile&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|''nothing''&lt;br /&gt;
|The path of the logo file image, for use in the Mods listing screen. The image must be in the root of the jar file, not in any subfolder thereof (e.g. the file is directly in &amp;lt;code&amp;gt;src/main/resources&amp;lt;/code&amp;gt;)&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;myAwesomeLogo.png&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;logoBlur&amp;lt;/code&amp;gt;&lt;br /&gt;
|boolean&lt;br /&gt;
|&amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;&lt;br /&gt;
|Whether to do some blurring on the mod's logo in the Mods listing screen. Has no effect if &amp;lt;code&amp;gt;logoFile&amp;lt;/code&amp;gt; is not set.&lt;br /&gt;
|&amp;lt;code&amp;gt;false&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;updateJSONURL&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|''nothing''&lt;br /&gt;
|The update JSON URL, used by the [[Update_Checker|update checker]]. This should never be a blank string, as that will cause an error.&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&amp;quot;http://myurl.me/path/to/update.json&amp;quot;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;modproperties&amp;lt;/code&amp;gt;&lt;br /&gt;
|table&lt;br /&gt;
|&amp;lt;code&amp;gt;{}&amp;lt;/code&amp;gt;&lt;br /&gt;
|A table of custom mod properties; this is not used for Forge, but is mainly for use by mods.&lt;br /&gt;
|&amp;lt;code&amp;gt;{ &amp;quot;useThing&amp;quot; = true }&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;credits&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|''nothing''&lt;br /&gt;
|Credits and acknowledgements for the mod, for use in the Mods listing screen. Can be any string.&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;This person and that guy&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;authors&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|''nothing''&lt;br /&gt;
|Authors for the mod, for use in the Mods listing screen. Can be any string.&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;ExampleDude&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;displayURL&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|''nothing''&lt;br /&gt;
|A URL, displayed on the Mods listing screen. Can be any string.&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&amp;quot;http://example.com/&amp;quot;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Dependency Configurations===&lt;br /&gt;
Mods can define dependencies for their mods, which are checked by Forge before loading mods. This is used for e.g. ensuring your mod loads after another, or hard-crashing if a mod with a specified version does not exist.&lt;br /&gt;
&lt;br /&gt;
These dependency configurations, like the mod properties, are defined by a new section starting with &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;[[dependencies.modid]]&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;, with &amp;lt;code&amp;gt;modid&amp;lt;/code&amp;gt; being the mod id that has this dependency. All properties from that line until the next header will become the properties of that dependency configuration.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!|Property&lt;br /&gt;
!|Type&lt;br /&gt;
!|Defaults&lt;br /&gt;
!|Description&lt;br /&gt;
!|Example&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;modId&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|'''mandatory'''&lt;br /&gt;
|The mod id of the dependency.&lt;br /&gt;
|&amp;lt;code&amp;gt;examplelibrary&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mandatory&amp;lt;/code&amp;gt;&lt;br /&gt;
|boolean&lt;br /&gt;
|'''mandatory'''&lt;br /&gt;
|Whether to crash if this dependency is not met.&lt;br /&gt;
|&amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;versionRange&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|The acceptable version range of the dependency, expressed as a [https://maven.apache.org/enforcer/enforcer-rules/versionRanges.html Maven version spec]. An empty string is an unbounded version range, which matches any version.&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;[1.0,2.0)&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;ordering&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;NONE&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|Defines if the mod must load before or after this dependency. The valid values are &amp;lt;code&amp;gt;BEFORE&amp;lt;/code&amp;gt; (must load before), &amp;lt;code&amp;gt;AFTER&amp;lt;/code&amp;gt; (must load after), and &amp;lt;code&amp;gt;NONE&amp;lt;/code&amp;gt; (does not care about order).&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;AFTER&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;side&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;BOTH&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|physical side]]. The valid values are &amp;lt;code&amp;gt;CLIENT&amp;lt;/code&amp;gt; (present on the client), &amp;lt;code&amp;gt;SERVER&amp;lt;/code&amp;gt; (present on the dedicated server), and &amp;lt;code&amp;gt;BOTH&amp;lt;/code&amp;gt; (present on both sides).&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;CLIENT&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Tip/Warning|When specifying dependency ordering between two or more mods, beware of cyclic order!&lt;br /&gt;
An example: if mod A must load before mod B, and mod B must load before mod A, the game will crash because of the circular cycle.}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Getting Started]]&lt;br /&gt;
[[Category:Beginner Topics]]&lt;/div&gt;</summary>
		<author><name>N1K-x</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Mods.toml&amp;diff=2943</id>
		<title>Mods.toml</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Mods.toml&amp;diff=2943"/>
		<updated>2021-09-01T11:16:23Z</updated>

		<summary type="html">&lt;p&gt;N1K-x: Fix version description&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Under construction}}&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;mods.toml&amp;lt;/code&amp;gt; file is read by the mod loader to determine what mods are packaged into your JAR file, and what information to display to the user in the Mods listing screen (accessible by pressing the &amp;quot;Mods&amp;quot; button on the main menu of the game). &lt;br /&gt;
&lt;br /&gt;
The file is formatted in [https://toml.io/en/ Tom's Obvious Minimal Language], or TOML for short. The example &amp;lt;code&amp;gt;mods.toml&amp;lt;/code&amp;gt; file in the MDK provides comments explaining the contents of the file. It should be stored under the &amp;lt;code&amp;gt;META-INF&amp;lt;/code&amp;gt; folder in your resources directory (&amp;lt;code&amp;gt;src/main/resources/META-INF/mods.toml&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Example &amp;lt;code&amp;gt;mods.toml&amp;lt;/code&amp;gt; file:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;TOML&amp;quot;&amp;gt;&lt;br /&gt;
modLoader=&amp;quot;javafml&amp;quot;&lt;br /&gt;
# Forge for 1.17.1 is version 37&lt;br /&gt;
loaderVersion=&amp;quot;[37,)&amp;quot;&lt;br /&gt;
license=&amp;quot;All rights reserved&amp;quot;&lt;br /&gt;
issueTrackerURL=&amp;quot;github.com/MinecraftForge/MinecraftForge/issues&amp;quot;&lt;br /&gt;
showAsResourcePack=false&lt;br /&gt;
&lt;br /&gt;
[[mods]]&lt;br /&gt;
    modId=&amp;quot;examplemod&amp;quot;&lt;br /&gt;
    version=&amp;quot;1.0.0.0&amp;quot;&lt;br /&gt;
    displayName=&amp;quot;Example Mod&amp;quot;&lt;br /&gt;
    updateJSONURL=&amp;quot;minecraftforge.net/versions.json&amp;quot;&lt;br /&gt;
    displayURL=&amp;quot;minecraftforge.net&amp;quot;&lt;br /&gt;
    logoFile=&amp;quot;logo.png&amp;quot;&lt;br /&gt;
    credits=&amp;quot;I'd like to thank my mother and father.&amp;quot;&lt;br /&gt;
    authors=&amp;quot;Author&amp;quot;&lt;br /&gt;
    description='''&lt;br /&gt;
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.&lt;br /&gt;
    '''&lt;br /&gt;
&lt;br /&gt;
[[dependencies.examplemod]]&lt;br /&gt;
    modId=&amp;quot;forge&amp;quot;&lt;br /&gt;
    mandatory=true&lt;br /&gt;
    versionRange=&amp;quot;[37,)&amp;quot;&lt;br /&gt;
    ordering=&amp;quot;NONE&amp;quot;&lt;br /&gt;
    side=&amp;quot;BOTH&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[[dependencies.examplemod]]&lt;br /&gt;
    modId=&amp;quot;minecraft&amp;quot;&lt;br /&gt;
    mandatory=true&lt;br /&gt;
    versionRange=&amp;quot;[1.17.1,1.18)&amp;quot;&lt;br /&gt;
    ordering=&amp;quot;NONE&amp;quot;&lt;br /&gt;
    side=&amp;quot;BOTH&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the &amp;lt;code&amp;gt;version&amp;lt;/code&amp;gt; is specified as&amp;lt;code&amp;gt;${file.jarVersion}&amp;lt;/code&amp;gt;, Forge will replace the string with the 'Implementation Version' specified in the jar manifest at runtime. Since the userdev environment has no jar manifest to pull from, it will be &amp;lt;code&amp;gt;NONE&amp;lt;/code&amp;gt; instead. As such, it is usually recommended to leave this field alone.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;mods.toml&amp;lt;/code&amp;gt; is split into three parts: the non-mod-specific properties, which are linked to the mod file; the mod properties, with a section for each mod; and dependency configurations, with a section for each mod's dependencies. Here is a table of attributes that may be given to a mod, where &amp;lt;code&amp;gt;mandatory&amp;lt;/code&amp;gt; means there is no default and the absence of the property causes an error.&lt;br /&gt;
&lt;br /&gt;
===Non-Mod-Specific Properties===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!|Property&lt;br /&gt;
!|Type&lt;br /&gt;
!|Defaults&lt;br /&gt;
!|Description&lt;br /&gt;
!|Example&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;modLoader&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|'''mandatory'''&lt;br /&gt;
|The language loader for the mod. Used to specify an alternative language for the mod, such as Kotlin, if one exists. The Forge-provided Java loader is &amp;lt;code&amp;gt;javafml&amp;lt;/code&amp;gt;.&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;javafml&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;loaderVersion&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|'''mandatory'''&lt;br /&gt;
|The acceptable version range of the language loader, expressed as a [https://maven.apache.org/enforcer/enforcer-rules/versionRanges.html Maven version spec]. For the Forge-provided Java loader, the version is the major version of the Forge version.&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;[37,)&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;license&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|'''mandatory'''&lt;br /&gt;
|The license for the mod(s) in this JAR. This string may be any valid string, but it is suggested to set the value to be the name of your license, and/or a link to that license.&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;GNU GPL v3, https://www.gnu.org/licenses/gpl-3.0.en.html&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;showAsResourcePack&amp;lt;/code&amp;gt;&lt;br /&gt;
|boolean&lt;br /&gt;
|&amp;lt;code&amp;gt;false&amp;lt;/code&amp;gt;&lt;br /&gt;
|Whether to display this mod's resources as a separate option in the resource pack menu. If disabled, the mod's resources will be rolled into the &amp;quot;Mod resources&amp;quot; pack.&lt;br /&gt;
|&amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;properties&amp;lt;/code&amp;gt;&lt;br /&gt;
|table&lt;br /&gt;
|&amp;lt;code&amp;gt;{}&amp;lt;/code&amp;gt;&lt;br /&gt;
|A table of custom substitution properties. This is used by &amp;lt;code&amp;gt;StringSubstitutor&amp;lt;/code&amp;gt; to replace values, using &amp;lt;code&amp;gt;${file.*}&amp;lt;/code&amp;gt;.&lt;br /&gt;
|&amp;lt;code&amp;gt;{ &amp;quot;thingy&amp;quot; = 1 }&amp;lt;/code&amp;gt;, used in &amp;lt;code&amp;gt;${file.thingy}&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;issueTrackerURL&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|''nothing''&lt;br /&gt;
|A URL for an issues tracker. This should never be a blank string, as that will cause an error.&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&amp;quot;http://my.issue.tracker/&amp;quot;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Mod Properties===&lt;br /&gt;
A mod entry is defined by a new section starting with a &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;[[mods]]&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; header (In TOML, the &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;[[mods]]&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; defines an [https://toml.io/en/v1.0.0-rc.2#array-of-tables array of tables]). All properties from that line until the next header will become the properties for that mod.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!|Property&lt;br /&gt;
!|Type&lt;br /&gt;
!|Defaults&lt;br /&gt;
!|Description&lt;br /&gt;
!|Example&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;modId&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|'''mandatory'''&lt;br /&gt;
|The mod's identifier (modid). This must match the following regex: &amp;lt;code&amp;gt;^[a-z][a-z0-9_-]{1,63}$&amp;lt;/code&amp;gt; (starts with a lowercase letter; other characters must be a lowercase letter, number, underscore or hyphen; must be 2-64 characters long).&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;examplemod&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;namespace&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|value of &amp;lt;code&amp;gt;modId&amp;lt;/code&amp;gt;&lt;br /&gt;
|An override namespace. Currently, there is no use for this property&lt;br /&gt;
|&amp;lt;code&amp;gt;example&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;version&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;1&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|The mod's version, ideally conforming to [[Semantic Versioning|semantic versioning]]. The default value in the MDK for this is &amp;lt;code&amp;gt;${file.jarVersion}&amp;lt;/code&amp;gt;, which is replaced at runtime with the &amp;lt;code&amp;gt;Implementation-Version&amp;lt;/code&amp;gt; found in the jar's manifest file.&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;0.2.4-beta1&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;displayName&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|value of &amp;lt;code&amp;gt;modId&amp;lt;/code&amp;gt;&lt;br /&gt;
|The display name of the mod, for use in the Mods listing screen&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;Example Mod&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;description&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;MISSING DESCRIPTION&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|The description of the mod, for use in the Mods listing screen. It's recommended to use a multiline string (surrounded by &amp;lt;code&amp;gt;'''&amp;lt;code&amp;gt;)&amp;lt;/code&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;Adds things and stuff. &amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;logoFile&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|''nothing''&lt;br /&gt;
|The path of the logo file image, for use in the Mods listing screen. The image must be in the root of the jar file, not in any subfolder thereof (e.g. the file is directly in &amp;lt;code&amp;gt;src/main/resources&amp;lt;/code&amp;gt;)&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;myAwesomeLogo.png&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;logoBlur&amp;lt;/code&amp;gt;&lt;br /&gt;
|boolean&lt;br /&gt;
|&amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;&lt;br /&gt;
|Whether to do some blurring on the mod's logo in the Mods listing screen. Has no effect if &amp;lt;code&amp;gt;logoFile&amp;lt;/code&amp;gt; is not set.&lt;br /&gt;
|&amp;lt;code&amp;gt;false&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;updateJSONURL&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|''nothing''&lt;br /&gt;
|The update JSON URL, used by the [[Update_Checker|update checker]]. This should never be a blank string, as that will cause an error.&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&amp;quot;http://myurl.me/path/to/update.json&amp;quot;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;modproperties&amp;lt;/code&amp;gt;&lt;br /&gt;
|table&lt;br /&gt;
|&amp;lt;code&amp;gt;{}&amp;lt;/code&amp;gt;&lt;br /&gt;
|A table of custom mod properties; this is not used for Forge, but is mainly for use by mods.&lt;br /&gt;
|&amp;lt;code&amp;gt;{ &amp;quot;useThing&amp;quot; = true }&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;credits&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|''nothing''&lt;br /&gt;
|Credits and acknowledgements for the mod, for use in the Mods listing screen. Can be any string.&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;This person and that guy&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;authors&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|''nothing''&lt;br /&gt;
|Authors for the mod, for use in the Mods listing screen. Can be any string.&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;ExampleDude&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;displayURL&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|''nothing''&lt;br /&gt;
|A URL, displayed on the Mods listing screen. Can be any string.&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&amp;quot;http://example.com/&amp;quot;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Dependency Configurations===&lt;br /&gt;
Mods can define dependencies for their mods, which are checked by Forge before loading mods. This is used for e.g. ensuring your mod loads after another, or hard-crashing if a mod with a specified version does not exist.&lt;br /&gt;
&lt;br /&gt;
These dependency configurations, like the mod properties, are defined by a new section starting with &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;[[dependencies.modid]]&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;, with &amp;lt;code&amp;gt;modid&amp;lt;/code&amp;gt; being the mod id that has this dependency. All properties from that line until the next header will become the properties of that dependency configuration.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!|Property&lt;br /&gt;
!|Type&lt;br /&gt;
!|Defaults&lt;br /&gt;
!|Description&lt;br /&gt;
!|Example&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;modId&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|'''mandatory'''&lt;br /&gt;
|The mod id of the dependency.&lt;br /&gt;
|&amp;lt;code&amp;gt;examplelibrary&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mandatory&amp;lt;/code&amp;gt;&lt;br /&gt;
|boolean&lt;br /&gt;
|'''mandatory'''&lt;br /&gt;
|Whether to crash if this dependency is not met.&lt;br /&gt;
|&amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;versionRange&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|The acceptable version range of the dependency, expressed as a [https://maven.apache.org/enforcer/enforcer-rules/versionRanges.html Maven version spec]. An empty string is an unbounded version range, which matches any version.&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;[1.0,2.0)&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;ordering&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;NONE&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|Defines if the mod must load before or after this dependency. The valid values are &amp;lt;code&amp;gt;BEFORE&amp;lt;/code&amp;gt; (must load before), &amp;lt;code&amp;gt;AFTER&amp;lt;/code&amp;gt; (must load after), and &amp;lt;code&amp;gt;NONE&amp;lt;/code&amp;gt; (does not care about order).&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;AFTER&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;side&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;BOTH&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|physical side]]. The valid values are &amp;lt;code&amp;gt;CLIENT&amp;lt;/code&amp;gt; (present on the client), &amp;lt;code&amp;gt;SERVER&amp;lt;/code&amp;gt; (present on the dedicated server), and &amp;lt;code&amp;gt;BOTH&amp;lt;/code&amp;gt; (present on both sides).&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;CLIENT&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Tip/Warning|When specifying dependency ordering between two or more mods, beware of cyclic order!&lt;br /&gt;
An example: if mod A must load before mod B, and mod B must load before mod A, the game will crash because of the circular cycle.}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Getting Started]]&lt;br /&gt;
[[Category:Beginner Topics]]&lt;/div&gt;</summary>
		<author><name>N1K-x</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Proper_Mod_Structuring&amp;diff=2942</id>
		<title>Proper Mod Structuring</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Proper_Mod_Structuring&amp;diff=2942"/>
		<updated>2021-09-01T11:08:42Z</updated>

		<summary type="html">&lt;p&gt;N1K-x: Properly reference the mods.toml file page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
The structure of your mod is important in keeping your mod organized, for both your benefit and the benefit of anyone who wishses to make a feature for your mod. A disorganized mod structure may cause headaches when someone is trying to update it to a higher version, especially if they cannot modify the package structure, due to i.e. licensing.&lt;br /&gt;
&lt;br /&gt;
{{Tip|Note that this page is only a recommendation for your mod structure; you may structure your mod in any way you see fit.}}&lt;br /&gt;
&lt;br /&gt;
== Packaging ==&lt;br /&gt;
&lt;br /&gt;
Pick a unique package name for your mod. If you own a URL associated with your project, you can use it as your top level package. For example if you own &amp;quot;example.com&amp;quot;, you may use &amp;lt;code&amp;gt;com.example&amp;lt;/code&amp;gt; as your top level package. &lt;br /&gt;
The next level package is usually your mod's ID: if your mod ID is &amp;lt;code&amp;gt;examplemod&amp;lt;/code&amp;gt;, your mod's package will be &amp;lt;code&amp;gt;com.example.examplemod&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Tip/Important|Do not use a domain for your top level package if you do not own that domain. It is perfectly acceptable to have your top level package be named with anything, such as your name/nickname, or the name of the mod (&amp;lt;code&amp;gt;me.exampledude.examplemod&amp;lt;/code&amp;gt;).}}&lt;br /&gt;
&lt;br /&gt;
=== Using Subpackages ===&lt;br /&gt;
&lt;br /&gt;
Rather than clutter up a single class and package with everything, it is recommended you break your mod into subpackages. Below are a few possible methods for laying out your folder structure though you may as well come up with your own layout too.&lt;br /&gt;
&lt;br /&gt;
* '''Group by Logic''': One possible strategy is to make subpackages for logical units of your mod. For example, if you have a block called Super Furnace you would put its block, its block entity and its item all under &amp;lt;code&amp;gt;feature/superfurnace&amp;lt;/code&amp;gt;.&lt;br /&gt;
* '''Group by Function''': Another common strategy is to make subpackages for grouping classes that have a common purpose. For example, your blocks classes can be under &amp;lt;code&amp;gt;blocks&amp;lt;/code&amp;gt;, your entities classes can be under &amp;lt;code&amp;gt;entities&amp;lt;/code&amp;gt;, your helper utilities can be under &amp;lt;code&amp;gt;helpers&amp;lt;/code&amp;gt;, etc.&lt;br /&gt;
&lt;br /&gt;
No matter how your final structure looks like it is highly recommended to add a &amp;lt;code&amp;gt;client&amp;lt;/code&amp;gt; subpackage under your main package. This helps to isolate your [[Sides|client-only code]] from the rest, such as your Screens and renderers.&lt;br /&gt;
&lt;br /&gt;
By keeping your code in clean subpackages, you can grow your mod much more organically.&lt;br /&gt;
&lt;br /&gt;
{{Tip|If you are unsure on how exactly you want to structure your mod it can be a good idea to look at the source of others to see how they did it.}}&lt;br /&gt;
&lt;br /&gt;
== Class Naming Schemes ==&lt;br /&gt;
&lt;br /&gt;
A common class naming scheme allows easier deciphering of the purpose of the class, and makes it easier for someone developing for your mod to find specific classes.&lt;br /&gt;
&lt;br /&gt;
The usual style is to use suffixes for your classes, for example:&lt;br /&gt;
&lt;br /&gt;
* An &amp;lt;code&amp;gt;Item&amp;lt;/code&amp;gt; called &amp;lt;code&amp;gt;PowerRing&amp;lt;/code&amp;gt; would have a class name of &amp;lt;code&amp;gt;PowerRingItem&amp;lt;/code&amp;gt;.&lt;br /&gt;
* A &amp;lt;code&amp;gt;Block&amp;lt;/code&amp;gt; called &amp;lt;code&amp;gt;NotDirt&amp;lt;/code&amp;gt; would have a class name of &amp;lt;code&amp;gt;NotDirtBlock&amp;lt;/code&amp;gt;.&lt;br /&gt;
* A &amp;lt;code&amp;gt;BlockEntity&amp;lt;/code&amp;gt; for a block called &amp;lt;code&amp;gt;SuperChewer&amp;lt;/code&amp;gt; would have a class name of &amp;lt;code&amp;gt;SuperChewerBlockEntity&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== The Mod File ==&lt;br /&gt;
&lt;br /&gt;
The main mod class - the class that is annotated with &amp;lt;code&amp;gt;@Mod&amp;lt;/code&amp;gt; - is usually put into the main package of your mod, and not placed into a subpackage. This allows an easier time to access this, as your main mod class is the entrypoint of your mod.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;@Mod&amp;lt;/code&amp;gt; annotation indicates to the mod loader that this class is the entry point of your mod. Each &amp;lt;code&amp;gt;@Mod&amp;lt;/code&amp;gt; annotation and their value should be paired with a mod id entry in your &amp;lt;code&amp;gt;mods.toml&amp;lt;/code&amp;gt; file.&lt;br /&gt;
&lt;br /&gt;
== mods.toml file ==&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;mods.toml&amp;lt;/code&amp;gt; file is read by the mod loader to determine what mods are packaged into your JAR file, and what information to display to the user in the Mods listing screen (accessible by pressing the &amp;quot;Mods&amp;quot; button on the main menu of the game). &lt;br /&gt;
&lt;br /&gt;
More information about the structure of this file and the possible configuration options available to you can be found on the [[Mods.toml file|dedicated page]].&lt;br /&gt;
&lt;br /&gt;
[[Category:Getting Started]]&lt;br /&gt;
[[Category:Beginner Topics]]&lt;/div&gt;</summary>
		<author><name>N1K-x</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Proper_Mod_Structuring&amp;diff=2941</id>
		<title>Proper Mod Structuring</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Proper_Mod_Structuring&amp;diff=2941"/>
		<updated>2021-09-01T11:02:24Z</updated>

		<summary type="html">&lt;p&gt;N1K-x: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
The structure of your mod is important in keeping your mod organized, for both your benefit and the benefit of anyone who wishses to make a feature for your mod. A disorganized mod structure may cause headaches when someone is trying to update it to a higher version, especially if they cannot modify the package structure, due to i.e. licensing.&lt;br /&gt;
&lt;br /&gt;
{{Tip|Note that this page is only a recommendation for your mod structure; you may structure your mod in any way you see fit.}}&lt;br /&gt;
&lt;br /&gt;
== Packaging ==&lt;br /&gt;
&lt;br /&gt;
Pick a unique package name for your mod. If you own a URL associated with your project, you can use it as your top level package. For example if you own &amp;quot;example.com&amp;quot;, you may use &amp;lt;code&amp;gt;com.example&amp;lt;/code&amp;gt; as your top level package. &lt;br /&gt;
The next level package is usually your mod's ID: if your mod ID is &amp;lt;code&amp;gt;examplemod&amp;lt;/code&amp;gt;, your mod's package will be &amp;lt;code&amp;gt;com.example.examplemod&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Tip/Important|Do not use a domain for your top level package if you do not own that domain. It is perfectly acceptable to have your top level package be named with anything, such as your name/nickname, or the name of the mod (&amp;lt;code&amp;gt;me.exampledude.examplemod&amp;lt;/code&amp;gt;).}}&lt;br /&gt;
&lt;br /&gt;
=== Using Subpackages ===&lt;br /&gt;
&lt;br /&gt;
Rather than clutter up a single class and package with everything, it is recommended you break your mod into subpackages. Below are a few possible methods for laying out your folder structure though you may as well come up with your own layout too.&lt;br /&gt;
&lt;br /&gt;
* '''Group by Logic''': One possible strategy is to make subpackages for logical units of your mod. For example, if you have a block called Super Furnace you would put its block, its block entity and its item all under &amp;lt;code&amp;gt;feature/superfurnace&amp;lt;/code&amp;gt;.&lt;br /&gt;
* '''Group by Function''': Another common strategy is to make subpackages for grouping classes that have a common purpose. For example, your blocks classes can be under &amp;lt;code&amp;gt;blocks&amp;lt;/code&amp;gt;, your entities classes can be under &amp;lt;code&amp;gt;entities&amp;lt;/code&amp;gt;, your helper utilities can be under &amp;lt;code&amp;gt;helpers&amp;lt;/code&amp;gt;, etc.&lt;br /&gt;
&lt;br /&gt;
No matter how your final structure looks like it is highly recommended to add a &amp;lt;code&amp;gt;client&amp;lt;/code&amp;gt; subpackage under your main package. This helps to isolate your [[Sides|client-only code]] from the rest, such as your Screens and renderers.&lt;br /&gt;
&lt;br /&gt;
By keeping your code in clean subpackages, you can grow your mod much more organically.&lt;br /&gt;
&lt;br /&gt;
{{Tip|If you are unsure on how exactly you want to structure your mod it can be a good idea to look at the source of others to see how they did it.}}&lt;br /&gt;
&lt;br /&gt;
== Class Naming Schemes ==&lt;br /&gt;
&lt;br /&gt;
A common class naming scheme allows easier deciphering of the purpose of the class, and makes it easier for someone developing for your mod to find specific classes.&lt;br /&gt;
&lt;br /&gt;
The usual style is to use suffixes for your classes, for example:&lt;br /&gt;
&lt;br /&gt;
* An &amp;lt;code&amp;gt;Item&amp;lt;/code&amp;gt; called &amp;lt;code&amp;gt;PowerRing&amp;lt;/code&amp;gt; would have a class name of &amp;lt;code&amp;gt;PowerRingItem&amp;lt;/code&amp;gt;.&lt;br /&gt;
* A &amp;lt;code&amp;gt;Block&amp;lt;/code&amp;gt; called &amp;lt;code&amp;gt;NotDirt&amp;lt;/code&amp;gt; would have a class name of &amp;lt;code&amp;gt;NotDirtBlock&amp;lt;/code&amp;gt;.&lt;br /&gt;
* A &amp;lt;code&amp;gt;BlockEntity&amp;lt;/code&amp;gt; for a block called &amp;lt;code&amp;gt;SuperChewer&amp;lt;/code&amp;gt; would have a class name of &amp;lt;code&amp;gt;SuperChewerBlockEntity&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== The Mod File ==&lt;br /&gt;
&lt;br /&gt;
The main mod class - the class that is annotated with &amp;lt;code&amp;gt;@Mod&amp;lt;/code&amp;gt; - is usually put into the main package of your mod, and not placed into a subpackage. This allows an easier time to access this, as your main mod class is the entrypoint of your mod.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;@Mod&amp;lt;/code&amp;gt; annotation indicates to the mod loader that this class is the entry point of your mod. Each &amp;lt;code&amp;gt;@Mod&amp;lt;/code&amp;gt; annotation and their value should be paired with a mod id entry in your &amp;lt;code&amp;gt;mods.toml&amp;lt;/code&amp;gt; file.&lt;br /&gt;
&lt;br /&gt;
== [[Mods.toml file]] ==&lt;br /&gt;
&lt;br /&gt;
[[Category:Getting Started]]&lt;br /&gt;
[[Category:Beginner Topics]]&lt;/div&gt;</summary>
		<author><name>N1K-x</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Main_Page&amp;diff=2940</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Main_Page&amp;diff=2940"/>
		<updated>2021-09-01T11:02:11Z</updated>

		<summary type="html">&lt;p&gt;N1K-x: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
&amp;lt;templatestyles src=&amp;quot;:Main_Page/styles.css&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;center title&amp;quot;&amp;gt;Forge Community Wiki&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The Forge Community Wiki exists so that the community can:&lt;br /&gt;
&lt;br /&gt;
* collectively keep track of major changes and updates to Forge and Vanilla code;&lt;br /&gt;
* create and edit articles with in-depth explanations about a variety of Forge-related subjects; and&lt;br /&gt;
* contribute example code and tutorials for both simple and difficult concepts.&lt;br /&gt;
&lt;br /&gt;
This wiki is editable by any registered user with an account. This is to allow tracking of harmful edits, but isn't imposing any annoying limits. We welcome any edit, however small. Join the [https://discord.gg/Nn42eAh Discord] to discuss changes and edits to the wiki with others and the staff.&lt;br /&gt;
&lt;br /&gt;
{{Supported versions}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;center round_warning&amp;quot;&amp;gt;&lt;br /&gt;
Please read the [[FCWMeta:Wiki Policy|wiki policy]] before editing!&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;center&amp;quot; style=&amp;quot;margin-bottom: 2em&amp;quot;&amp;gt;&lt;br /&gt;
The current ''Latest'' version is '''1.17.1'''. The current ''Long Term Support (LTS)'' version is '''1.16.5'''. '''1.15.2''' is currently in ''grace/LTS''.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;box_container center&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;h3&amp;gt;Beginner Topics&amp;lt;/h3&amp;gt;&lt;br /&gt;
* [[Getting Started]]&lt;br /&gt;
* [[Proper Mod Structuring]]&lt;br /&gt;
* [[Mods.toml file]]&lt;br /&gt;
* [[Debug Profiler|The Debug Profiler]]&lt;br /&gt;
* [[Version Checker]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;h3&amp;gt;Common Concepts&amp;lt;/h3&amp;gt;&lt;br /&gt;
* [[Sides|Understanding Sides]]&lt;br /&gt;
* [[Events|Understanding Events]]&lt;br /&gt;
* [[Registration]]&lt;br /&gt;
* [[Internationalization]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;h3&amp;gt;Forge Conventions&amp;lt;/h3&amp;gt;&lt;br /&gt;
* [[Semantic Versioning]]&lt;br /&gt;
* [[Stages of Modloading]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;h3&amp;gt;Resources and Data&amp;lt;/h3&amp;gt;&lt;br /&gt;
* [[Using Resources|Introduction]]&lt;br /&gt;
* [[Recipes]]&lt;br /&gt;
* [[Tags]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;h3&amp;gt;Blocks&amp;lt;/h3&amp;gt;&lt;br /&gt;
* [[Making Blocks|Creating Blocks]]&lt;br /&gt;
* [[Understanding Blockstates]] &lt;br /&gt;
* [[Interacting With Blocks|Block Interactions]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;h3&amp;gt;Items&amp;lt;/h3&amp;gt;&lt;br /&gt;
* [[Making Items]]&lt;br /&gt;
* [[Making Tools]]&lt;br /&gt;
* [[BlockEntityWithoutLevelRenderer|&amp;lt;tt&amp;gt;BlockEntityWithoutLevelRenderer&amp;lt;/tt&amp;gt;]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;h3&amp;gt;Data Generation&amp;lt;/h3&amp;gt;&lt;br /&gt;
* [[Datageneration|Introduction]]&lt;br /&gt;
* [[Datageneration/Recipes|Recipes]]&lt;br /&gt;
* [[Datageneration/Tags|Tags]]&lt;br /&gt;
* [[Datageneration/Loot_Tables|Loot Tables]]&lt;br /&gt;
* [[Datageneration/I18n|Localization]]&lt;br /&gt;
* [[Datageneration/States and Models|&amp;lt;tt&amp;gt;BlockState&amp;lt;/tt&amp;gt;s and Models]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;h3&amp;gt;Block Entities&amp;lt;/h3&amp;gt;&lt;br /&gt;
* [[Block Entities|Introduction]]&lt;br /&gt;
* [[Block Entity Renderer|&amp;lt;tt&amp;gt;BlockEntityRenderer&amp;lt;/tt&amp;gt;]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;h3&amp;gt;Models&amp;lt;/h3&amp;gt;&lt;br /&gt;
* [[Introduction to Models|Introduction]]&lt;br /&gt;
* [[Model JSONs]]&lt;br /&gt;
* [[BlockState JSONs]]&lt;br /&gt;
* [[Coloring textures dynamically|Dynamically Colored Textures]]&lt;br /&gt;
* [[Item Properties]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;h3&amp;gt;Handling Information&amp;lt;/h3&amp;gt;&lt;br /&gt;
* [[Understanding Networking|Introduction]]&lt;br /&gt;
* [[Using NBT|Named Binary Tag (NBT)]]&lt;br /&gt;
* [[Using FriendlyByteBuf|Using &amp;lt;tt&amp;gt;FriendlyByteBuf&amp;lt;/tt&amp;gt;]]&lt;br /&gt;
* [[Sending Packets|Sending and Receiving Packets]]&lt;br /&gt;
* [[Using SimpleChannel|Using &amp;lt;tt&amp;gt;SimpleChannel&amp;lt;/tt&amp;gt;]]&lt;br /&gt;
* [[Networking with Entities]]&lt;br /&gt;
* [[DynamicOps|Using DynamicOps]]&lt;br /&gt;
* [[Codecs|Using Codecs]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;h3&amp;gt;Data Storage&amp;lt;/h3&amp;gt;&lt;br /&gt;
* [[Capabilities|Understanding Capabilities]] &lt;br /&gt;
* [[Capabilities/Attaching|Attaching Capabilities]]&lt;br /&gt;
* [[Saved Data]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;h3&amp;gt;Game Effects&amp;lt;/h3&amp;gt;&lt;br /&gt;
* [[Mob Effects]]&lt;br /&gt;
* [[Potions]]&lt;br /&gt;
* [[Particles]]&lt;br /&gt;
* [[Sounds]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;h3&amp;gt;Events&amp;lt;/h3&amp;gt;&lt;br /&gt;
* [[Events|Understanding Events]]&lt;br /&gt;
* [[Entity Events]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;h3&amp;gt;Others&amp;lt;/h3&amp;gt;&lt;br /&gt;
* [[Dependencies]]&lt;br /&gt;
* [[Dynamic Loot Modification]]&lt;br /&gt;
* [[Components|Components and Translation Keys]]&lt;br /&gt;
* [[Key Mappings]]&lt;br /&gt;
* [[Access Transformers]]&lt;br /&gt;
* [[Toolchain]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;h3&amp;gt;Recipes&amp;lt;/h3&amp;gt;&lt;br /&gt;
* [[Recipes]]&lt;br /&gt;
* [[Custom Recipes|Custom Recipe Types]]&lt;br /&gt;
* [[Datageneration/Recipes|Datageneration]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>N1K-x</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Mods.toml&amp;diff=2939</id>
		<title>Mods.toml</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Mods.toml&amp;diff=2939"/>
		<updated>2021-09-01T11:00:42Z</updated>

		<summary type="html">&lt;p&gt;N1K-x: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Under construction}}&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;mods.toml&amp;lt;/code&amp;gt; file is read by the mod loader to determine what mods are packaged into your JAR file, and what information to display to the user in the Mods listing screen (accessible by pressing the &amp;quot;Mods&amp;quot; button on the main menu of the game). &lt;br /&gt;
&lt;br /&gt;
The file is formatted in [https://toml.io/en/ Tom's Obvious Minimal Language], or TOML for short. The example &amp;lt;code&amp;gt;mods.toml&amp;lt;/code&amp;gt; file in the MDK provides comments explaining the contents of the file. It should be stored under the &amp;lt;code&amp;gt;META-INF&amp;lt;/code&amp;gt; folder in your resources directory (&amp;lt;code&amp;gt;src/main/resources/META-INF/mods.toml&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Example &amp;lt;code&amp;gt;mods.toml&amp;lt;/code&amp;gt; file:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;TOML&amp;quot;&amp;gt;&lt;br /&gt;
modLoader=&amp;quot;javafml&amp;quot;&lt;br /&gt;
# Forge for 1.17.1 is version 37&lt;br /&gt;
loaderVersion=&amp;quot;[37,)&amp;quot;&lt;br /&gt;
license=&amp;quot;All rights reserved&amp;quot;&lt;br /&gt;
issueTrackerURL=&amp;quot;github.com/MinecraftForge/MinecraftForge/issues&amp;quot;&lt;br /&gt;
showAsResourcePack=false&lt;br /&gt;
&lt;br /&gt;
[[mods]]&lt;br /&gt;
    modId=&amp;quot;examplemod&amp;quot;&lt;br /&gt;
    version=&amp;quot;1.0.0.0&amp;quot;&lt;br /&gt;
    displayName=&amp;quot;Example Mod&amp;quot;&lt;br /&gt;
    updateJSONURL=&amp;quot;minecraftforge.net/versions.json&amp;quot;&lt;br /&gt;
    displayURL=&amp;quot;minecraftforge.net&amp;quot;&lt;br /&gt;
    logoFile=&amp;quot;logo.png&amp;quot;&lt;br /&gt;
    credits=&amp;quot;I'd like to thank my mother and father.&amp;quot;&lt;br /&gt;
    authors=&amp;quot;Author&amp;quot;&lt;br /&gt;
    description='''&lt;br /&gt;
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.&lt;br /&gt;
    '''&lt;br /&gt;
&lt;br /&gt;
[[dependencies.examplemod]]&lt;br /&gt;
    modId=&amp;quot;forge&amp;quot;&lt;br /&gt;
    mandatory=true&lt;br /&gt;
    versionRange=&amp;quot;[37,)&amp;quot;&lt;br /&gt;
    ordering=&amp;quot;NONE&amp;quot;&lt;br /&gt;
    side=&amp;quot;BOTH&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[[dependencies.examplemod]]&lt;br /&gt;
    modId=&amp;quot;minecraft&amp;quot;&lt;br /&gt;
    mandatory=true&lt;br /&gt;
    versionRange=&amp;quot;[1.17.1,1.18)&amp;quot;&lt;br /&gt;
    ordering=&amp;quot;NONE&amp;quot;&lt;br /&gt;
    side=&amp;quot;BOTH&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the &amp;lt;code&amp;gt;version&amp;lt;/code&amp;gt; is specified as&amp;lt;code&amp;gt;${file.jarVersion}&amp;lt;/code&amp;gt;, Forge will replace the string with the 'Implementation Version' specified in the jar manifest at runtime. Since the userdev environment has no jar manifest to pull from, it will be &amp;lt;code&amp;gt;NONE&amp;lt;/code&amp;gt; instead. As such, it is usually recommended to leave this field alone.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;mods.toml&amp;lt;/code&amp;gt; is split into three parts: the non-mod-specific properties, which are linked to the mod file; the mod properties, with a section for each mod; and dependency configurations, with a section for each mod's dependencies. Here is a table of attributes that may be given to a mod, where &amp;lt;code&amp;gt;mandatory&amp;lt;/code&amp;gt; means there is no default and the absence of the property causes an error.&lt;br /&gt;
&lt;br /&gt;
===Non-Mod-Specific Properties===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!|Property&lt;br /&gt;
!|Type&lt;br /&gt;
!|Defaults&lt;br /&gt;
!|Description&lt;br /&gt;
!|Example&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;modLoader&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|'''mandatory'''&lt;br /&gt;
|The language loader for the mod. Used to specify an alternative language for the mod, such as Kotlin, if one exists. The Forge-provided Java loader is &amp;lt;code&amp;gt;javafml&amp;lt;/code&amp;gt;.&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;javafml&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;loaderVersion&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|'''mandatory'''&lt;br /&gt;
|The acceptable version range of the language loader, expressed as a [https://maven.apache.org/enforcer/enforcer-rules/versionRanges.html Maven version spec]. For the Forge-provided Java loader, the version is the major version of the Forge version.&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;[37,)&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;license&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|'''mandatory'''&lt;br /&gt;
|The license for the mod(s) in this JAR. This string may be any valid string, but it is suggested to set the value to be the name of your license, and/or a link to that license.&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;GNU GPL v3, https://www.gnu.org/licenses/gpl-3.0.en.html&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;showAsResourcePack&amp;lt;/code&amp;gt;&lt;br /&gt;
|boolean&lt;br /&gt;
|&amp;lt;code&amp;gt;false&amp;lt;/code&amp;gt;&lt;br /&gt;
|Whether to display this mod's resources as a separate option in the resource pack menu. If disabled, the mod's resources will be rolled into the &amp;quot;Mod resources&amp;quot; pack.&lt;br /&gt;
|&amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;properties&amp;lt;/code&amp;gt;&lt;br /&gt;
|table&lt;br /&gt;
|&amp;lt;code&amp;gt;{}&amp;lt;/code&amp;gt;&lt;br /&gt;
|A table of custom substitution properties. This is used by &amp;lt;code&amp;gt;StringSubstitutor&amp;lt;/code&amp;gt; to replace values, using &amp;lt;code&amp;gt;${file.*}&amp;lt;/code&amp;gt;.&lt;br /&gt;
|&amp;lt;code&amp;gt;{ &amp;quot;thingy&amp;quot; = 1 }&amp;lt;/code&amp;gt;, used in &amp;lt;code&amp;gt;${file.thingy}&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;issueTrackerURL&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|''nothing''&lt;br /&gt;
|A URL for an issues tracker. This should never be a blank string, as that will cause an error.&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&amp;quot;http://my.issue.tracker/&amp;quot;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Mod Properties===&lt;br /&gt;
A mod entry is defined by a new section starting with a &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;[[mods]]&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; header (In TOML, the &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;[[mods]]&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; defines an [https://toml.io/en/v1.0.0-rc.2#array-of-tables array of tables]). All properties from that line until the next header will become the properties for that mod.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!|Property&lt;br /&gt;
!|Type&lt;br /&gt;
!|Defaults&lt;br /&gt;
!|Description&lt;br /&gt;
!|Example&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;modId&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|'''mandatory'''&lt;br /&gt;
|The mod's identifier (modid). This must match the following regex: &amp;lt;code&amp;gt;^[a-z][a-z0-9_-]{1,63}$&amp;lt;/code&amp;gt; (starts with a lowercase letter; other characters must be a lowercase letter, number, underscore or hyphen; must be 2-64 characters long).&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;examplemod&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;namespace&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|value of &amp;lt;code&amp;gt;modId&amp;lt;/code&amp;gt;&lt;br /&gt;
|An override namespace. Currently, there is no use for this property&lt;br /&gt;
|&amp;lt;code&amp;gt;example&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;version&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;1&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|.), ideally conforming to [[Semantic_Versioning&amp;gt;Semantic Versioning]]. The default value in the MDK for this is &amp;lt;code&amp;gt;${file.jarVersion}&amp;lt;/code&amp;gt;, which is replaced at runtime with the &amp;lt;code&amp;gt;Implementation-Version&amp;lt;/code&amp;gt; found in the jar's manifest file.&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;0.2.4-beta1&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;displayName&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|value of &amp;lt;code&amp;gt;modId&amp;lt;/code&amp;gt;&lt;br /&gt;
|The display name of the mod, for use in the Mods listing screen&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;Example Mod&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;description&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;MISSING DESCRIPTION&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|The description of the mod, for use in the Mods listing screen. It's recommended to use a multiline string (surrounded by &amp;lt;code&amp;gt;'''&amp;lt;code&amp;gt;)&amp;lt;/code&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;Adds things and stuff. &amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;logoFile&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|''nothing''&lt;br /&gt;
|The path of the logo file image, for use in the Mods listing screen. The image must be in the root of the jar file, not in any subfolder thereof (e.g. the file is directly in &amp;lt;code&amp;gt;src/main/resources&amp;lt;/code&amp;gt;)&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;myAwesomeLogo.png&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;logoBlur&amp;lt;/code&amp;gt;&lt;br /&gt;
|boolean&lt;br /&gt;
|&amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;&lt;br /&gt;
|Whether to do some blurring on the mod's logo in the Mods listing screen. Has no effect if &amp;lt;code&amp;gt;logoFile&amp;lt;/code&amp;gt; is not set.&lt;br /&gt;
|&amp;lt;code&amp;gt;false&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;updateJSONURL&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|''nothing''&lt;br /&gt;
|The update JSON URL, used by the [Update_Checker update checker]. This should never be a blank string, as that will cause an error.&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&amp;quot;http://myurl.me/path/to/update.json&amp;quot;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;modproperties&amp;lt;/code&amp;gt;&lt;br /&gt;
|table&lt;br /&gt;
|&amp;lt;code&amp;gt;{}&amp;lt;/code&amp;gt;&lt;br /&gt;
|A table of custom mod properties; this is not used for Forge, but is mainly for use by mods.&lt;br /&gt;
|&amp;lt;code&amp;gt;{ &amp;quot;useThing&amp;quot; = true }&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;credits&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|''nothing''&lt;br /&gt;
|Credits and acknowledgements for the mod, for use in the Mods listing screen. Can be any string.&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;This person and that guy&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;authors&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|''nothing''&lt;br /&gt;
|Authors for the mod, for use in the Mods listing screen. Can be any string.&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;ExampleDude&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;displayURL&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|''nothing''&lt;br /&gt;
|A URL, displayed on the Mods listing screen. Can be any string.&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&amp;quot;http://example.com/&amp;quot;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Dependency Configurations===&lt;br /&gt;
Mods can define dependencies for their mods, which are checked by Forge before loading mods. This is used for e.g. ensuring your mod loads after another, or hard-crashing if a mod with a specified version does not exist.&lt;br /&gt;
&lt;br /&gt;
These dependency configurations, like the mod properties, are defined by a new section starting with &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;[[dependencies.modid]]&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;, with &amp;lt;code&amp;gt;modid&amp;lt;/code&amp;gt; being the mod id that has this dependency. All properties from that line until the next header will become the properties of that dependency configuration.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!|Property&lt;br /&gt;
!|Type&lt;br /&gt;
!|Defaults&lt;br /&gt;
!|Description&lt;br /&gt;
!|Example&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;modId&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|'''mandatory'''&lt;br /&gt;
|The mod id of the dependency.&lt;br /&gt;
|&amp;lt;code&amp;gt;examplelibrary&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mandatory&amp;lt;/code&amp;gt;&lt;br /&gt;
|boolean&lt;br /&gt;
|'''mandatory'''&lt;br /&gt;
|Whether to crash if this dependency is not met.&lt;br /&gt;
|&amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;versionRange&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|The acceptable version range of the dependency, expressed as a [https://maven.apache.org/enforcer/enforcer-rules/versionRanges.html Maven version spec]. An empty string is an unbounded version range, which matches any version.&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;[1.0,2.0)&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;ordering&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;NONE&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|Defines if the mod must load before or after this dependency. The valid values are &amp;lt;code&amp;gt;BEFORE&amp;lt;/code&amp;gt; (must load before), &amp;lt;code&amp;gt;AFTER&amp;lt;/code&amp;gt; (must load after), and &amp;lt;code&amp;gt;NONE&amp;lt;/code&amp;gt; (does not care about order).&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;AFTER&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;side&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;BOTH&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|physical side]]. The valid values are &amp;lt;code&amp;gt;CLIENT&amp;lt;/code&amp;gt; (present on the client), &amp;lt;code&amp;gt;SERVER&amp;lt;/code&amp;gt; (present on the dedicated server), and &amp;lt;code&amp;gt;BOTH&amp;lt;/code&amp;gt; (present on both sides).&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;CLIENT&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Tip/Warning|When specifying dependency ordering between two or more mods, beware of cyclic order!&lt;br /&gt;
An example: if mod A must load before mod B, and mod B must load before mod A, the game will crash because of the circular cycle.}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Getting Started]]&lt;br /&gt;
[[Category:Beginner Topics]]&lt;/div&gt;</summary>
		<author><name>N1K-x</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Mods.toml&amp;diff=2938</id>
		<title>Mods.toml</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Mods.toml&amp;diff=2938"/>
		<updated>2021-09-01T11:00:13Z</updated>

		<summary type="html">&lt;p&gt;N1K-x: Created page with &amp;quot;{{Under construction}}  The &amp;lt;code&amp;gt;mods.toml&amp;lt;/code&amp;gt; file is read by the mod loader to determine what mods are packaged into your JAR file, and what information to display to th...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Under construction}}&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;mods.toml&amp;lt;/code&amp;gt; file is read by the mod loader to determine what mods are packaged into your JAR file, and what information to display to the user in the Mods listing screen (accessible by pressing the &amp;quot;Mods&amp;quot; button on the main menu of the game). &lt;br /&gt;
&lt;br /&gt;
The file is formatted in [https://toml.io/en/ Tom's Obvious Minimal Language], or TOML for short. The example &amp;lt;code&amp;gt;mods.toml&amp;lt;/code&amp;gt; file in the MDK provides comments explaining the contents of the file. It should be stored under the &amp;lt;code&amp;gt;META-INF&amp;lt;/code&amp;gt; folder in your resources directory (&amp;lt;code&amp;gt;src/main/resources/META-INF/mods.toml&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Example &amp;lt;code&amp;gt;mods.toml&amp;lt;/code&amp;gt; file:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;TOML&amp;quot;&amp;gt;&lt;br /&gt;
modLoader=&amp;quot;javafml&amp;quot;&lt;br /&gt;
# Forge for 1.17.1 is version 37&lt;br /&gt;
loaderVersion=&amp;quot;[37,)&amp;quot;&lt;br /&gt;
license=&amp;quot;All rights reserved&amp;quot;&lt;br /&gt;
issueTrackerURL=&amp;quot;github.com/MinecraftForge/MinecraftForge/issues&amp;quot;&lt;br /&gt;
showAsResourcePack=false&lt;br /&gt;
&lt;br /&gt;
[[mods]]&lt;br /&gt;
    modId=&amp;quot;examplemod&amp;quot;&lt;br /&gt;
    version=&amp;quot;1.0.0.0&amp;quot;&lt;br /&gt;
    displayName=&amp;quot;Example Mod&amp;quot;&lt;br /&gt;
    updateJSONURL=&amp;quot;minecraftforge.net/versions.json&amp;quot;&lt;br /&gt;
    displayURL=&amp;quot;minecraftforge.net&amp;quot;&lt;br /&gt;
    logoFile=&amp;quot;logo.png&amp;quot;&lt;br /&gt;
    credits=&amp;quot;I'd like to thank my mother and father.&amp;quot;&lt;br /&gt;
    authors=&amp;quot;Author&amp;quot;&lt;br /&gt;
    description='''&lt;br /&gt;
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.&lt;br /&gt;
    '''&lt;br /&gt;
&lt;br /&gt;
[[dependencies.examplemod]]&lt;br /&gt;
    modId=&amp;quot;forge&amp;quot;&lt;br /&gt;
    mandatory=true&lt;br /&gt;
    versionRange=&amp;quot;[37,)&amp;quot;&lt;br /&gt;
    ordering=&amp;quot;NONE&amp;quot;&lt;br /&gt;
    side=&amp;quot;BOTH&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[[dependencies.examplemod]]&lt;br /&gt;
    modId=&amp;quot;minecraft&amp;quot;&lt;br /&gt;
    mandatory=true&lt;br /&gt;
    versionRange=&amp;quot;[1.17.1,1.18)&amp;quot;&lt;br /&gt;
    ordering=&amp;quot;NONE&amp;quot;&lt;br /&gt;
    side=&amp;quot;BOTH&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the &amp;lt;code&amp;gt;version&amp;lt;/code&amp;gt; is specified as&amp;lt;code&amp;gt;${file.jarVersion}&amp;lt;/code&amp;gt;, Forge will replace the string with the 'Implementation Version' specified in the jar manifest at runtime. Since the userdev environment has no jar manifest to pull from, it will be &amp;lt;code&amp;gt;NONE&amp;lt;/code&amp;gt; instead. As such, it is usually recommended to leave this field alone.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;mods.toml&amp;lt;/code&amp;gt; is split into three parts: the non-mod-specific properties, which are linked to the mod file; the mod properties, with a section for each mod; and dependency configurations, with a section for each mod's dependencies. Here is a table of attributes that may be given to a mod, where &amp;lt;code&amp;gt;mandatory&amp;lt;/code&amp;gt; means there is no default and the absence of the property causes an error.&lt;br /&gt;
&lt;br /&gt;
===Non-Mod-Specific Properties===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!|Property&lt;br /&gt;
!|Type&lt;br /&gt;
!|Defaults&lt;br /&gt;
!|Description&lt;br /&gt;
!|Example&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;modLoader&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|'''mandatory'''&lt;br /&gt;
|The language loader for the mod. Used to specify an alternative language for the mod, such as Kotlin, if one exists. The Forge-provided Java loader is &amp;lt;code&amp;gt;javafml&amp;lt;/code&amp;gt;.&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;javafml&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;loaderVersion&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|'''mandatory'''&lt;br /&gt;
|The acceptable version range of the language loader, expressed as a [https://maven.apache.org/enforcer/enforcer-rules/versionRanges.html Maven version spec]. For the Forge-provided Java loader, the version is the major version of the Forge version.&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;[37,)&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;license&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|'''mandatory'''&lt;br /&gt;
|The license for the mod(s) in this JAR. This string may be any valid string, but it is suggested to set the value to be the name of your license, and/or a link to that license.&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;GNU GPL v3, https://www.gnu.org/licenses/gpl-3.0.en.html&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;showAsResourcePack&amp;lt;/code&amp;gt;&lt;br /&gt;
|boolean&lt;br /&gt;
|&amp;lt;code&amp;gt;false&amp;lt;/code&amp;gt;&lt;br /&gt;
|Whether to display this mod's resources as a separate option in the resource pack menu. If disabled, the mod's resources will be rolled into the &amp;quot;Mod resources&amp;quot; pack.&lt;br /&gt;
|&amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;properties&amp;lt;/code&amp;gt;&lt;br /&gt;
|table&lt;br /&gt;
|&amp;lt;code&amp;gt;{}&amp;lt;/code&amp;gt;&lt;br /&gt;
|A table of custom substitution properties. This is used by &amp;lt;code&amp;gt;StringSubstitutor&amp;lt;/code&amp;gt; to replace values, using &amp;lt;code&amp;gt;${file.*}&amp;lt;/code&amp;gt;.&lt;br /&gt;
|&amp;lt;code&amp;gt;{ &amp;quot;thingy&amp;quot; = 1 }&amp;lt;/code&amp;gt;, used in &amp;lt;code&amp;gt;${file.thingy}&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;issueTrackerURL&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|''nothing''&lt;br /&gt;
|A URL for an issues tracker. This should never be a blank string, as that will cause an error.&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&amp;quot;http://my.issue.tracker/&amp;quot;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Mod Properties===&lt;br /&gt;
A mod entry is defined by a new section starting with a &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;[[mods]]&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; header (In TOML, the &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;[[mods]]&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; defines an [https://toml.io/en/v1.0.0-rc.2#array-of-tables array of tables]). All properties from that line until the next header will become the properties for that mod.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!|Property&lt;br /&gt;
!|Type&lt;br /&gt;
!|Defaults&lt;br /&gt;
!|Description&lt;br /&gt;
!|Example&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;modId&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|'''mandatory'''&lt;br /&gt;
|The mod's identifier (modid). This must match the following regex: &amp;lt;code&amp;gt;^[a-z][a-z0-9_-]{1,63}$&amp;lt;/code&amp;gt; (starts with a lowercase letter; other characters must be a lowercase letter, number, underscore or hyphen; must be 2-64 characters long).&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;examplemod&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;namespace&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|value of &amp;lt;code&amp;gt;modId&amp;lt;/code&amp;gt;&lt;br /&gt;
|An override namespace. Currently, there is no use for this property&lt;br /&gt;
|&amp;lt;code&amp;gt;example&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;version&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;1&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|.), ideally conforming to [[Semantic_Versioning&amp;gt;Semantic Versioning]]. The default value in the MDK for this is &amp;lt;code&amp;gt;${file.jarVersion}&amp;lt;/code&amp;gt;, which is replaced at runtime with the &amp;lt;code&amp;gt;Implementation-Version&amp;lt;/code&amp;gt; found in the jar's manifest file.&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;0.2.4-beta1&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;displayName&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|value of &amp;lt;code&amp;gt;modId&amp;lt;/code&amp;gt;&lt;br /&gt;
|The display name of the mod, for use in the Mods listing screen&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;Example Mod&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;description&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;MISSING DESCRIPTION&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|The description of the mod, for use in the Mods listing screen. It's recommended to use a multiline string (surrounded by &amp;lt;code&amp;gt;'''&amp;lt;code&amp;gt;)&amp;lt;/code&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;Adds things and stuff. &amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;logoFile&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|''nothing''&lt;br /&gt;
|The path of the logo file image, for use in the Mods listing screen. The image must be in the root of the jar file, not in any subfolder thereof (e.g. the file is directly in &amp;lt;code&amp;gt;src/main/resources&amp;lt;/code&amp;gt;)&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;myAwesomeLogo.png&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;logoBlur&amp;lt;/code&amp;gt;&lt;br /&gt;
|boolean&lt;br /&gt;
|&amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;&lt;br /&gt;
|Whether to do some blurring on the mod's logo in the Mods listing screen. Has no effect if &amp;lt;code&amp;gt;logoFile&amp;lt;/code&amp;gt; is not set.&lt;br /&gt;
|&amp;lt;code&amp;gt;false&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;updateJSONURL&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|''nothing''&lt;br /&gt;
|The update JSON URL, used by the [Update_Checker update checker]. This should never be a blank string, as that will cause an error.&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&amp;quot;http://myurl.me/path/to/update.json&amp;quot;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;modproperties&amp;lt;/code&amp;gt;&lt;br /&gt;
|table&lt;br /&gt;
|&amp;lt;code&amp;gt;{}&amp;lt;/code&amp;gt;&lt;br /&gt;
|A table of custom mod properties; this is not used for Forge, but is mainly for use by mods.&lt;br /&gt;
|&amp;lt;code&amp;gt;{ &amp;quot;useThing&amp;quot; = true }&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;credits&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|''nothing''&lt;br /&gt;
|Credits and acknowledgements for the mod, for use in the Mods listing screen. Can be any string.&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;This person and that guy&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;authors&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|''nothing''&lt;br /&gt;
|Authors for the mod, for use in the Mods listing screen. Can be any string.&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;ExampleDude&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;displayURL&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|''nothing''&lt;br /&gt;
|A URL, displayed on the Mods listing screen. Can be any string.&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&amp;quot;http://example.com/&amp;quot;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Dependency Configurations===&lt;br /&gt;
Mods can define dependencies for their mods, which are checked by Forge before loading mods. This is used for e.g. ensuring your mod loads after another, or hard-crashing if a mod with a specified version does not exist.&lt;br /&gt;
&lt;br /&gt;
These dependency configurations, like the mod properties, are defined by a new section starting with &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;[[dependencies.modid]]&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;, with &amp;lt;code&amp;gt;modid&amp;lt;/code&amp;gt; being the mod id that has this dependency. All properties from that line until the next header will become the properties of that dependency configuration.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!|Property&lt;br /&gt;
!|Type&lt;br /&gt;
!|Defaults&lt;br /&gt;
!|Description&lt;br /&gt;
!|Example&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;modId&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|'''mandatory'''&lt;br /&gt;
|The mod id of the dependency.&lt;br /&gt;
|&amp;lt;code&amp;gt;examplelibrary&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mandatory&amp;lt;/code&amp;gt;&lt;br /&gt;
|boolean&lt;br /&gt;
|'''mandatory'''&lt;br /&gt;
|Whether to crash if this dependency is not met.&lt;br /&gt;
|&amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;versionRange&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|The acceptable version range of the dependency, expressed as a [https://maven.apache.org/enforcer/enforcer-rules/versionRanges.html Maven version spec]. An empty string is an unbounded version range, which matches any version.&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;[1.0,2.0)&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;ordering&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;NONE&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|Defines if the mod must load before or after this dependency. The valid values are &amp;lt;code&amp;gt;BEFORE&amp;lt;/code&amp;gt; (must load before), &amp;lt;code&amp;gt;AFTER&amp;lt;/code&amp;gt; (must load after), and &amp;lt;code&amp;gt;NONE&amp;lt;/code&amp;gt; (does not care about order).&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;AFTER&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;side&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;BOTH&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|physical side]]. The valid values are &amp;lt;code&amp;gt;CLIENT&amp;lt;/code&amp;gt; (present on the client), &amp;lt;code&amp;gt;SERVER&amp;lt;/code&amp;gt; (present on the dedicated server), and &amp;lt;code&amp;gt;BOTH&amp;lt;/code&amp;gt; (present on both sides).&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;CLIENT&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Tip/Warning|When specifying dependency ordering between two or more mods, beware of cyclic order!&lt;br /&gt;
An example: if mod A must load before mod B, and mod B must load before mod A, the game will crash because of the circular cycle.}}&lt;/div&gt;</summary>
		<author><name>N1K-x</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Proper_Mod_Structuring&amp;diff=2817</id>
		<title>Proper Mod Structuring</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Proper_Mod_Structuring&amp;diff=2817"/>
		<updated>2021-07-29T10:14:38Z</updated>

		<summary type="html">&lt;p&gt;N1K-x: Add another possible way of laying out subpackages&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
The structure of your mod is important in keeping your mod organized, for both your benefit and the benefit of anyone who wishses to make a feature for your mod. A disorganized mod structure may cause headaches when someone is trying to update it to a higher version, especially if they cannot modify the package structure, due to i.e. licensing.&lt;br /&gt;
&lt;br /&gt;
{{Tip|Note that this page is only a recommendation for your mod structure; you may structure your mod in any way you see fit.}}&lt;br /&gt;
&lt;br /&gt;
== Packaging ==&lt;br /&gt;
&lt;br /&gt;
Pick a unique package name for your mod. If you own a URL associated with your project, you can use it as your top level package. For example if you own &amp;quot;example.com&amp;quot;, you may use &amp;lt;code&amp;gt;com.example&amp;lt;/code&amp;gt; as your top level package. &lt;br /&gt;
The next level package is usually your mod's ID: if your mod ID is &amp;lt;code&amp;gt;examplemod&amp;lt;/code&amp;gt;, your mod's package will be &amp;lt;code&amp;gt;com.example.examplemod&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Tip/Important|Do not use a domain for your top level package if you do not own that domain. It is perfectly acceptable to have your top level package be named with anything, such as your name/nickname, or the name of the mod (&amp;lt;code&amp;gt;me.exampledude.examplemod&amp;lt;/code&amp;gt;).}}&lt;br /&gt;
&lt;br /&gt;
=== Using Subpackages ===&lt;br /&gt;
&lt;br /&gt;
Rather than clutter up a single class and package with everything, it is recommended you break your mod into subpackages. Below are a few possible methods for laying out your folder structure though you may as well come up with your own layout too.&lt;br /&gt;
&lt;br /&gt;
* '''Group by Logic''': One possible strategy is to make subpackages for logical units of your mod. For example, if you have a block called Super Furnace you would put its block, its block entity and its item all under &amp;lt;code&amp;gt;feature/superfurnace&amp;lt;/code&amp;gt;.&lt;br /&gt;
* '''Group by Function''': Another common strategy is to make subpackages for grouping classes that have a common purpose. For example, your blocks classes can be under &amp;lt;code&amp;gt;blocks&amp;lt;/code&amp;gt;, your entities classes can be under &amp;lt;code&amp;gt;entities&amp;lt;/code&amp;gt;, your helper utilities can be under &amp;lt;code&amp;gt;helpers&amp;lt;/code&amp;gt;, etc.&lt;br /&gt;
&lt;br /&gt;
No matter how your final structure looks like it is highly recommended to add a &amp;lt;code&amp;gt;client&amp;lt;/code&amp;gt; subpackage under your main package. This helps to isolate your [[Sides|client-only code]] from the rest, such as your GUIs and renderers.&lt;br /&gt;
&lt;br /&gt;
By keeping your code in clean subpackages, you can grow your mod much more organically.&lt;br /&gt;
&lt;br /&gt;
{{Tip|If you are unsure on how exactly you want to structure your mod it can be a good idea to look at the source of others to see how they did it.}}&lt;br /&gt;
&lt;br /&gt;
== Class Naming Schemes ==&lt;br /&gt;
&lt;br /&gt;
A common class naming scheme allows easier deciphering of the purpose of the class, and makes it easier for someone developing for your mod to find specific classes.&lt;br /&gt;
&lt;br /&gt;
The usual style is to use suffixes for your classes, for example:&lt;br /&gt;
&lt;br /&gt;
* An &amp;lt;code&amp;gt;Item&amp;lt;/code&amp;gt; called &amp;lt;code&amp;gt;PowerRing&amp;lt;/code&amp;gt; would have a class name of &amp;lt;code&amp;gt;PowerRingItem&amp;lt;/code&amp;gt;.&lt;br /&gt;
* A &amp;lt;code&amp;gt;Block&amp;lt;/code&amp;gt; called &amp;lt;code&amp;gt;NotDirt&amp;lt;/code&amp;gt; would have a class name of &amp;lt;code&amp;gt;NotDirtBlock&amp;lt;/code&amp;gt;.&lt;br /&gt;
* A &amp;lt;code&amp;gt;BlockEntity&amp;lt;/code&amp;gt; for a block called &amp;lt;code&amp;gt;SuperChewer&amp;lt;/code&amp;gt; would have a class name of &amp;lt;code&amp;gt;SuperChewerBlockEntity&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== The Mod File ==&lt;br /&gt;
&lt;br /&gt;
The main mod class - the class that is annotated with &amp;lt;code&amp;gt;@Mod&amp;lt;/code&amp;gt; - is usually put into the main package of your mod, and not placed into a subpackage. This allows an easier time to access this, as your main mod class is the entrypoint of your mod.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;@Mod&amp;lt;/code&amp;gt; annotation indicates to the mod loader that this class is the entry point of your mod. Each &amp;lt;code&amp;gt;@Mod&amp;lt;/code&amp;gt; annotation and their value should be paired with a mod id entry in your &amp;lt;code&amp;gt;mods.toml&amp;lt;/code&amp;gt; file.&lt;br /&gt;
&lt;br /&gt;
==The &amp;lt;code&amp;gt;mods.toml&amp;lt;/code&amp;gt; file==&lt;br /&gt;
The &amp;lt;code&amp;gt;mods.toml&amp;lt;/code&amp;gt; file is read by the mod loader to determine what mods are packaged into your JAR file, and what information to display to the user in the Mods listing screen (accessible by pressing the &amp;quot;Mods&amp;quot; button on the main menu of the game). &lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;mods.toml&amp;lt;/code&amp;gt; file is formatted in [https://toml.io/en/ Tom's Obvious Minimal Language]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
, or TOML for short. The example &amp;lt;code&amp;gt;mods.toml&amp;lt;/code&amp;gt; file in the MDK provides comments explaining the contents of the file. It should be stored under the &amp;lt;code&amp;gt;META-INF&amp;lt;/code&amp;gt; folder in your resources directory (&amp;lt;code&amp;gt;src/main/resources/META-INF/mods.toml&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Example &amp;lt;code&amp;gt;mods.toml&amp;lt;/code&amp;gt; file&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;TOML&amp;quot;&amp;gt;&lt;br /&gt;
modLoader=&amp;quot;javafml&amp;quot;&lt;br /&gt;
# Forge for 1.16.5 is version 36&lt;br /&gt;
loaderVersion=&amp;quot;[36,)&amp;quot;&lt;br /&gt;
license=&amp;quot;All rights reserved&amp;quot;&lt;br /&gt;
issueTrackerURL=&amp;quot;github.com/MinecraftForge/MinecraftForge/issues&amp;quot;&lt;br /&gt;
showAsResourcePack=false&lt;br /&gt;
&lt;br /&gt;
[[mods]]&lt;br /&gt;
    modId=&amp;quot;examplemod&amp;quot;&lt;br /&gt;
    version=&amp;quot;1.0.0.0&amp;quot;&lt;br /&gt;
    displayName=&amp;quot;Example Mod&amp;quot;&lt;br /&gt;
    updateJSONURL=&amp;quot;minecraftforge.net/versions.json&amp;quot;&lt;br /&gt;
    displayURL=&amp;quot;minecraftforge.net&amp;quot;&lt;br /&gt;
    logoFile=&amp;quot;logo.png&amp;quot;&lt;br /&gt;
    credits=&amp;quot;I'd like to thank my mother and father.&amp;quot;&lt;br /&gt;
    authors=&amp;quot;Author&amp;quot;&lt;br /&gt;
    description='''&lt;br /&gt;
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.&lt;br /&gt;
    '''&lt;br /&gt;
&lt;br /&gt;
[[dependencies.examplemod]]&lt;br /&gt;
    modId=&amp;quot;forge&amp;quot;&lt;br /&gt;
    mandatory=true&lt;br /&gt;
    versionRange=&amp;quot;[36,)&amp;quot;&lt;br /&gt;
    ordering=&amp;quot;NONE&amp;quot;&lt;br /&gt;
    side=&amp;quot;BOTH&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[[dependencies.examplemod]]&lt;br /&gt;
    modId=&amp;quot;minecraft&amp;quot;&lt;br /&gt;
    mandatory=true&lt;br /&gt;
    versionRange=&amp;quot;[1.16.5]&amp;quot;&lt;br /&gt;
    ordering=&amp;quot;NONE&amp;quot;&lt;br /&gt;
    side=&amp;quot;BOTH&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If the &amp;lt;code&amp;gt;version&amp;lt;/code&amp;gt; is specified as&amp;lt;code&amp;gt;${file.jarVersion}&amp;lt;/code&amp;gt;, Forge will replace the string with the 'Implementation Version' specified in the jar manifest at runtime. Since the userdev environment has no jar manifest to pull from, it will be &amp;lt;code&amp;gt;NONE&amp;lt;/code&amp;gt; instead. As such, it is usually recommended to leave this field alone.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;mods.toml&amp;lt;/code&amp;gt; is split into three parts: the non-mod-specific properties, which are linked to the mod file; the mod properties, with a section for each mod; and dependency configurations, with a section for each mod's dependencies.Here is a table of attributes that may be given to a mod, where&amp;lt;code&amp;gt;mandatory&amp;lt;/code&amp;gt;means there is no default and the absence of the property causes an error.&lt;br /&gt;
===Non-Mod-Specific Properties===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!|Property&lt;br /&gt;
!|Type&lt;br /&gt;
!|Defaults&lt;br /&gt;
!|Description&lt;br /&gt;
!|Example&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;modLoader&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|'''mandatory'''&lt;br /&gt;
|The language loader for the mod. Used to specify an alternative language for the mod, such as Kotlin, if one exists. The Forge-provided Java loader is &amp;lt;code&amp;gt;javafml&amp;lt;/code&amp;gt;.&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;javafml&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;loaderVersion&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|'''mandatory'''&lt;br /&gt;
|The acceptable version range of the language loader, expressed as a [https://maven.apache.org/enforcer/enforcer-rules/versionRanges.html Maven version spec]. For the Forge-provided Java loader, the version is the major version of the Forge version.&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;[36,)&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;license&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|'''mandatory'''&lt;br /&gt;
|The license for the mod(s) in this JAR. This string may be any valid string, but it is suggested to set the value to be the name of your license, and/or a link to that license.&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;GNU GPL v3, https://www.gnu.org/licenses/gpl-3.0.en.html&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;showAsResourcePack&amp;lt;/code&amp;gt;&lt;br /&gt;
|boolean&lt;br /&gt;
|&amp;lt;code&amp;gt;false&amp;lt;/code&amp;gt;&lt;br /&gt;
|Whether to display this mod's resources as a separate option in the resource pack menu. If disabled, the mod's resources will be rolled into the &amp;quot;Mod resources&amp;quot; pack.&lt;br /&gt;
|&amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;properties&amp;lt;/code&amp;gt;&lt;br /&gt;
|table&lt;br /&gt;
|&amp;lt;code&amp;gt;{}&amp;lt;/code&amp;gt;&lt;br /&gt;
|A table of custom substitution properties. This is used by &amp;lt;code&amp;gt;StringSubstitutor&amp;lt;/code&amp;gt; to replace values, using &amp;lt;code&amp;gt;${file.*}&amp;lt;/code&amp;gt;.&lt;br /&gt;
|&amp;lt;code&amp;gt;{ &amp;quot;thingy&amp;quot; = 1 }&amp;lt;/code&amp;gt;, used in &amp;lt;code&amp;gt;${file.thingy}&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;issueTrackerURL&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|''nothing''&lt;br /&gt;
|A URL for an issues tracker. This should never be a blank string, as that will cause an error.&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&amp;quot;http://my.issue.tracker/&amp;quot;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Mod Properties===&lt;br /&gt;
A mod entry is defined by a new section starting with a &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;[[mods]]&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; header (In TOML, the &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;[[mods]]&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; defines an [https://toml.io/en/v1.0.0-rc.2#array-of-tables array of tables]). All properties from that line until the next header will become the properties for that mod.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!|Property&lt;br /&gt;
!|Type&lt;br /&gt;
!|Defaults&lt;br /&gt;
!|Description&lt;br /&gt;
!|Example&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;modId&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|'''mandatory'''&lt;br /&gt;
|The mod's identifier (modid). This must match the following regex: &amp;lt;code&amp;gt;^[a-z][a-z0-9_-]{1,63}$&amp;lt;/code&amp;gt; (starts with a lowercase letter; other characters must be a lowercase letter, number, underscore or hyphen; must be 2-64 characters long).&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;examplemod&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;namespace&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|value of &amp;lt;code&amp;gt;modId&amp;lt;/code&amp;gt;&lt;br /&gt;
|An override namespace. Currently, there is no use for this property&lt;br /&gt;
|&amp;lt;code&amp;gt;example&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;version&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;1&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|.), ideally conforming to [[Semantic_Versioning&amp;gt;Semantic Versioning]]. The default value in the MDK for this is &amp;lt;code&amp;gt;${file.jarVersion}&amp;lt;/code&amp;gt;, which is replaced at runtime with the &amp;lt;code&amp;gt;Implementation-Version&amp;lt;/code&amp;gt; found in the jar's manifest file.&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;0.2.4-beta1&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;displayName&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|value of &amp;lt;code&amp;gt;modId&amp;lt;/code&amp;gt;&lt;br /&gt;
|The display name of the mod, for use in the Mods listing screen&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;Example Mod&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;description&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;MISSING DESCRIPTION&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|The description of the mod, for use in the Mods listing screen. It's recommended to use a multiline string (surrounded by &amp;lt;code&amp;gt;'''&amp;lt;code&amp;gt;)&amp;lt;/code&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;Adds things and stuff. &amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;logoFile&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|''nothing''&lt;br /&gt;
|The path of the logo file image, for use in the Mods listing screen. The image must be in the root of the jar file, not in any subfolder thereof (e.g. the file is directly in &amp;lt;code&amp;gt;src/main/resources&amp;lt;/code&amp;gt;)&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;myAwesomeLogo.png&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;logoBlur&amp;lt;/code&amp;gt;&lt;br /&gt;
|boolean&lt;br /&gt;
|&amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;&lt;br /&gt;
|Whether to do some blurring on the mod's logo in the Mods listing screen. Has no effect if &amp;lt;code&amp;gt;logoFile&amp;lt;/code&amp;gt; is not set.&lt;br /&gt;
|&amp;lt;code&amp;gt;false&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;updateJSONURL&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|''nothing''&lt;br /&gt;
|The update JSON URL, used by the [Update_Checker update checker]. This should never be a blank string, as that will cause an error.&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&amp;quot;http://myurl.me/path/to/update.json&amp;quot;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;modproperties&amp;lt;/code&amp;gt;&lt;br /&gt;
|table&lt;br /&gt;
|&amp;lt;code&amp;gt;{}&amp;lt;/code&amp;gt;&lt;br /&gt;
|A table of custom mod properties; this is not used for Forge, but is mainly for use by mods.&lt;br /&gt;
|&amp;lt;code&amp;gt;{ &amp;quot;useThing&amp;quot; = true }&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;credits&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|''nothing''&lt;br /&gt;
|Credits and acknowledgements for the mod, for use in the Mods listing screen. Can be any string.&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;This person and that guy&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;authors&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|''nothing''&lt;br /&gt;
|Authors for the mod, for use in the Mods listing screen. Can be any string.&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;ExampleDude&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;displayURL&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|''nothing''&lt;br /&gt;
|A URL, displayed on the Mods listing screen. Can be any string.&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&amp;quot;http://example.com/&amp;quot;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Dependency Configurations===&lt;br /&gt;
Mods can define dependencies for their mods, which are checked by Forge before loading mods. This is used for e.g. ensuring your mod loads after another, or hard-crashing if a mod with a specified version does not exist.&lt;br /&gt;
&lt;br /&gt;
These dependency configurations, like the mod properties, are defined by a new section starting with &amp;lt;code&amp;gt;[[dependencies.]]&amp;lt;/code&amp;gt;, with &amp;lt;code&amp;gt;&amp;lt;/code&amp;gt; being the mod id that has this dependency. All properties from that line until the next header will become the properties of that dependency configuration.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!|Property&lt;br /&gt;
!|Type&lt;br /&gt;
!|Defaults&lt;br /&gt;
!|Description&lt;br /&gt;
!|Example&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;modId&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|'''mandatory'''&lt;br /&gt;
|The mod id of the dependency.&lt;br /&gt;
|&amp;lt;code&amp;gt;examplelibrary&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mandatory&amp;lt;/code&amp;gt;&lt;br /&gt;
|boolean&lt;br /&gt;
|'''mandatory'''&lt;br /&gt;
|Whether to crash if this dependency is not met.&lt;br /&gt;
|&amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;versionRange&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|The acceptable version range of the dependency, expressed as a [https://maven.apache.org/enforcer/enforcer-rules/versionRanges.html Maven version spec]. An empty string is an unbounded version range, which matches any version.&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;[1.0,2.0)&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;ordering&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;NONE&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|Defines if the mod must load before or after this dependency. The valid values are &amp;lt;code&amp;gt;BEFORE&amp;lt;/code&amp;gt; (must load before), &amp;lt;code&amp;gt;AFTER&amp;lt;/code&amp;gt; (must load after), and &amp;lt;code&amp;gt;NONE&amp;lt;/code&amp;gt; (does not care about order).&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;AFTER&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;side&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;BOTH&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|physical side]]. The valid values are &amp;lt;code&amp;gt;CLIENT&amp;lt;/code&amp;gt; (present on the client), &amp;lt;code&amp;gt;SERVER&amp;lt;/code&amp;gt; (present on the dedicated server), and &amp;lt;code&amp;gt;BOTH&amp;lt;/code&amp;gt; (present on both sides).&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;CLIENT&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Tip/Warning|When specifying dependency ordering between two or more mods, beware of cyclic order!&lt;br /&gt;
An example: if mod A must load before mod B, and mod B must load before mod A, the game will crash because of the circular cycle.}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Getting Started]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Beginner Topics]]&lt;/div&gt;</summary>
		<author><name>N1K-x</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Getting_Started&amp;diff=2816</id>
		<title>Getting Started</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Getting_Started&amp;diff=2816"/>
		<updated>2021-07-29T09:22:04Z</updated>

		<summary type="html">&lt;p&gt;N1K-x: Change the gradle version&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Minecraft Forge''' is a modding framework, designed to allow different mods to load and work together to be compatible. Through the years, there has been many changes in the Forge tooling to make working with mods as seamless as possible. It is now easier than ever to start making your own mod.&lt;br /&gt;
&lt;br /&gt;
== The Mod Development Kit ==&lt;br /&gt;
The '''Mod Development Kit''' or '''MDK''' is a downloadable archive that contains the basic skeleton for starting a new mod. It contains the following files and folders:&lt;br /&gt;
&lt;br /&gt;
{{Tree list}}&lt;br /&gt;
* '''The Mod Development Kit'''&lt;br /&gt;
** &amp;lt;code&amp;gt;gradle/wrapper/&amp;lt;/code&amp;gt; - The folder containing the [https://docs.gradle.org/7.1.1/userguide/gradle_wrapper.html Gradle wrapper]'', Forge uses a Snapshot Version of Gradle '''7.2'''''&lt;br /&gt;
** &amp;lt;code&amp;gt;src&amp;lt;/code&amp;gt; - The sources folder&lt;br /&gt;
*** &amp;lt;code&amp;gt;main&amp;lt;/code&amp;gt; - The &amp;lt;code&amp;gt;main&amp;lt;/code&amp;gt; source set&lt;br /&gt;
**** &amp;lt;code&amp;gt;java&amp;lt;/code&amp;gt; - The java sources for the &amp;lt;code&amp;gt;main&amp;lt;/code&amp;gt; source set&lt;br /&gt;
***** ...&lt;br /&gt;
**** &amp;lt;code&amp;gt;resources&amp;lt;/code&amp;gt; - The resources for the &amp;lt;code&amp;gt;main&amp;lt;/code&amp;gt; source set&lt;br /&gt;
***** &amp;lt;code&amp;gt;META-INF&amp;lt;/code&amp;gt; - The folder for '''meta'''data '''inf'''ormation files&amp;lt;ref&amp;gt;[https://stackoverflow.com/a/6075320/14416954 StackOverflow answer]: ''... Basically, if it was stored in META-INF, it was Meta-data Information...''&amp;lt;/ref&amp;gt;&lt;br /&gt;
****** &amp;lt;code&amp;gt;mods.toml&amp;lt;/code&amp;gt; - The [[Proper Mod Structuring#The mods.toml file|&amp;lt;tt&amp;gt;mods.toml&amp;lt;/tt&amp;gt; file]], where mods are declared&lt;br /&gt;
***** &amp;lt;code&amp;gt;pack.mcmeta&amp;lt;/code&amp;gt; - File used by Minecraft to [[mc:Data Pack#pack.mcmeta|identify data and resource packs]]&lt;br /&gt;
** &amp;lt;code&amp;gt;.gitattributes&amp;lt;/code&amp;gt; - Used by [[wikipedia:Git|Git]] for specifying attributes for files&amp;lt;ref&amp;gt;[https://git-scm.com/docs/gitattributes Official git documentation on &amp;lt;tt&amp;gt;.gitattributes&amp;lt;/tt&amp;gt;]&amp;lt;/ref&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;.gitignore&amp;lt;/code&amp;gt; - Used by Git for specifying intentionally untracked/ignored files&amp;lt;ref&amp;gt;[https://git-scm.com/docs/gitignore Official git documentation on &amp;lt;tt&amp;gt;.gitignore&amp;lt;/tt&amp;gt;]&amp;lt;/ref&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;build.gradle&amp;lt;/code&amp;gt; - The Gradle buildscript, which defines the project and tasks&amp;lt;ref&amp;gt;[https://docs.gradle.org/7.1.1/userguide/tutorial_using_tasks.html Gradle User Guide for 7.1.1: ''Build Script Basics'']&amp;lt;/ref&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;changelog.txt&amp;lt;/code&amp;gt; - The Forge version changelog&lt;br /&gt;
** &amp;lt;code&amp;gt;CREDITS.txt&amp;lt;/code&amp;gt; - Forge's credits/''thank you'' file&lt;br /&gt;
** &amp;lt;code&amp;gt;gradle.properties&amp;lt;/code&amp;gt; - The Gradle properties file, for defining additional variables and options&amp;lt;ref&amp;gt;[https://docs.gradle.org/7.1.1/userguide/build_environment.html#sec:gradle_configuration_properties Gradle User Guide for 7.1.1: ''Build Environment § Gradle properties'']&amp;lt;/ref&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;gradlew&amp;lt;/code&amp;gt; - The *nix shell file for executing the Gradle wrapper&lt;br /&gt;
** &amp;lt;code&amp;gt;gradlew.bat&amp;lt;/code&amp;gt; - The Windows batch file for executing the Gradle wrapper&lt;br /&gt;
** &amp;lt;code&amp;gt;LICENSE.txt&amp;lt;/code&amp;gt; - File containing the licensing information for Forge and libraries&lt;br /&gt;
** &amp;lt;code&amp;gt;README.txt&amp;lt;/code&amp;gt; - Readme file with the basic setup instructions&lt;br /&gt;
{{Tree list/end}}&lt;br /&gt;
&lt;br /&gt;
== Basic MDK Setup ==&lt;br /&gt;
# Download the MDK from the [https://files.minecraftforge.net/ official Minecraft Forge download site] and extract the MDK into an empty folder.&lt;br /&gt;
# Open your IDE of choice, and import the project as a Gradle project.&lt;br /&gt;
#* For '''Eclipse''': &amp;lt;tt&amp;gt;File &amp;gt; Import &amp;gt; Gradle &amp;gt; Existing Gradle Project&amp;lt;/tt&amp;gt;, select the folder for the &amp;lt;tt&amp;gt;Project root directory&amp;lt;/tt&amp;gt;, click &amp;lt;tt&amp;gt;Finish&amp;lt;/tt&amp;gt;&lt;br /&gt;
#* For '''IntelliJ IDEA''': &amp;lt;tt&amp;gt;File &amp;gt; Open&amp;lt;/tt&amp;gt;, select and open the folder, select the &amp;lt;tt&amp;gt;build.gradle&amp;lt;/tt&amp;gt; file, click &amp;lt;tt&amp;gt;OK&amp;lt;/tt&amp;gt;, click &amp;lt;tt&amp;gt;Open as Project&amp;lt;/tt&amp;gt;&lt;br /&gt;
# Wait for the setup process to complete and the Minecraft sources are decompiled.&lt;br /&gt;
# Generate the run configurations for your IDE using the appropriate Gradle task. &amp;lt;br&amp;gt;These tasks can be run on the command line using ''(Windows)'' &amp;lt;code&amp;gt;gradlew gen***Runs&amp;lt;/code&amp;gt; or ''(*nix)'' &amp;lt;code&amp;gt;./gradlew gen***Runs&amp;lt;/code&amp;gt;.&lt;br /&gt;
#* For ''Eclipse'': the task is &amp;lt;code&amp;gt;genEclipseRuns&amp;lt;/code&amp;gt;; to run in the IDE directly, open the &amp;lt;tt&amp;gt;Gradle Tasks&amp;lt;/tt&amp;gt; tab on the bottom panel, ''wait until the tasks have loaded'' then expand the folder, expand the &amp;lt;tt&amp;gt;fg_runs&amp;lt;/tt&amp;gt; folder, then double-click &amp;lt;tt&amp;gt;genEclipseRuns&amp;lt;/tt&amp;gt;.&lt;br /&gt;
#* For ''IntelliJ IDEA'': the task is &amp;lt;code&amp;gt;genIntellijRuns&amp;lt;/code&amp;gt;; to run in the IDE directly, open the &amp;lt;tt&amp;gt;Gradle&amp;lt;/tt&amp;gt; on the right, expand the project folder, double-click &amp;lt;tt&amp;gt;Tasks &amp;gt; fg_runs &amp;gt; genIntellijRuns&amp;lt;/tt&amp;gt;.&lt;br /&gt;
#* For ''Visual Studio Code'': the task is &amp;lt;code&amp;gt;genVSCodeRuns&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Tip|The most popular IDEs used by Forge and mod developers are [https://www.eclipse.org/eclipseide/ Eclipse] and [https://www.jetbrains.com/idea/ IntelliJ IDEA]. While Visual Studio Code has a run generation task, because of its relative unpopularity as an IDE for Minecraft modding, the user will have to self-diagnose any issues that may arise from their use of it.}}&lt;br /&gt;
&lt;br /&gt;
== Customizing the MDK ==&lt;br /&gt;
The MDK provides default values for the buildscript and &amp;lt;tt&amp;gt;mods.toml&amp;lt;/tt&amp;gt; file. These values should be replaced with your own mod's information.&lt;br /&gt;
&lt;br /&gt;
All edits should be done below the &amp;lt;code&amp;gt;apply plugin: 'net.minecraftforge.gradle'&amp;lt;/code&amp;gt; line. The lines above it are required for the Forge MDK to work correctly, and should not be modified without proper knowledge.&lt;br /&gt;
* All references to &amp;lt;code&amp;gt;examplemod&amp;lt;/code&amp;gt; in the buildscript should be replaced with your modid.&lt;br /&gt;
** Use your IDE's find-and-replace function to quickly replace these values.&lt;br /&gt;
** Pick a unique and memorable modid. The modid must be between 2 and 64 characters, and must consist of lowercase letters, numbers, underscores (&amp;lt;code&amp;gt;_&amp;lt;/code&amp;gt;) and hyphens (&amp;lt;code&amp;gt;-&amp;lt;/code&amp;gt;). The recommendation is to avoid using acronyms and abbreviations.&lt;br /&gt;
* Change the &amp;lt;code&amp;gt;archivesBaseName&amp;lt;/code&amp;gt; variable to your modid. This is used as the base name for the JAR file when you build your mod, and as the &amp;lt;tt&amp;gt;artifactId&amp;lt;/tt&amp;gt; of your mod's [https://maven.apache.org/pom.html#Maven_Coordinates maven coordinates].&lt;br /&gt;
* Change the &amp;lt;code&amp;gt;group&amp;lt;/code&amp;gt; to your [[Proper Mod Structuring#Packaging|unique root java package]]. This is used as the &amp;lt;tt&amp;gt;groupId&amp;lt;/tt&amp;gt; of your mod's maven coordinates.&lt;br /&gt;
* In the &amp;lt;code&amp;gt;jar&amp;lt;/code&amp;gt; task, change the values of the &amp;lt;code&amp;gt;Specification-Vendor&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;Implementation-Vendor&amp;lt;/code&amp;gt; keys to your username/brand name or other form of identification.&lt;br /&gt;
* ''Optional suggestion: '' Change the &amp;lt;code&amp;gt;version&amp;lt;/code&amp;gt; variable to have a 0 as the major version (ex. &amp;lt;code&amp;gt;'0.1'&amp;lt;/code&amp;gt;. This is to follow [[Semantic Versioning#During Development|semantic versioning guidelines]] for versions in active development.&lt;br /&gt;
&lt;br /&gt;
== Building and Testing ==&lt;br /&gt;
You can test your mod in the development environment using either your IDE's run configurations and built-in debugging utilities, or by running the &amp;lt;code&amp;gt;run*&amp;lt;/code&amp;gt; task as defined by the buildscript's run configurations.&lt;br /&gt;
&lt;br /&gt;
There are three default run configurations with the MDK:&lt;br /&gt;
* &amp;lt;code&amp;gt;runClient&amp;lt;/code&amp;gt;, for starting the client.&lt;br /&gt;
* &amp;lt;code&amp;gt;runServer&amp;lt;/code&amp;gt;, for starting the dedicated server. ''You will need to accept the EULA through the &amp;lt;tt&amp;gt;eula.txt&amp;lt;/tt&amp;gt; after running the server for the first time.''&lt;br /&gt;
* &amp;lt;code&amp;gt;runData&amp;lt;/code&amp;gt;, for starting the client in [[Datageneration|data generation]] mode.&lt;br /&gt;
&lt;br /&gt;
{{Tip|Always test your mod in both the client and the dedicated server, even if you are making a one-sided mod. Mods should not crash when running on both sides, and one-sided mods should not crash if they run on the wrong side.}}&lt;br /&gt;
&lt;br /&gt;
You can build your mod's final JAR using the &amp;lt;code&amp;gt;build&amp;lt;/code&amp;gt; task. The resulting JAR will be located in the &amp;lt;code&amp;gt;build/libs&amp;lt;/code&amp;gt; folder under your project directory.&lt;br /&gt;
&lt;br /&gt;
[[Category:Getting Started]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Beginner Topics]]&lt;/div&gt;</summary>
		<author><name>N1K-x</name></author>
	</entry>
</feed>