<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://necessewiki.com/mediawiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Jamesp1989</id>
	<title>Necesse Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://necessewiki.com/mediawiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Jamesp1989"/>
	<link rel="alternate" type="text/html" href="https://necessewiki.com/Special:Contributions/Jamesp1989"/>
	<updated>2026-04-12T18:32:48Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.41.0</generator>
	<entry>
		<id>https://necessewiki.com/mediawiki/index.php?title=Demon_bar&amp;diff=25010</id>
		<title>Demon bar</title>
		<link rel="alternate" type="text/html" href="https://necessewiki.com/mediawiki/index.php?title=Demon_bar&amp;diff=25010"/>
		<updated>2026-04-10T16:09:10Z</updated>

		<summary type="html">&lt;p&gt;Jamesp1989: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[Demonic_Bar]]&lt;/div&gt;</summary>
		<author><name>Jamesp1989</name></author>
	</entry>
	<entry>
		<id>https://necessewiki.com/mediawiki/index.php?title=Demon_bar&amp;diff=25009</id>
		<title>Demon bar</title>
		<link rel="alternate" type="text/html" href="https://necessewiki.com/mediawiki/index.php?title=Demon_bar&amp;diff=25009"/>
		<updated>2026-04-10T16:08:49Z</updated>

		<summary type="html">&lt;p&gt;Jamesp1989: Redirected page to Demonic Bar&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[Demonic_Bar]]&lt;br /&gt;
A demon bar can be crafted at a demon workstation for either 1 gold bar, 3 copper bars, or 2 iron bars. Additionally, it can be dropped by the evil&#039;s protector boss.&lt;/div&gt;</summary>
		<author><name>Jamesp1989</name></author>
	</entry>
	<entry>
		<id>https://necessewiki.com/mediawiki/index.php?title=Modding&amp;diff=24731</id>
		<title>Modding</title>
		<link rel="alternate" type="text/html" href="https://necessewiki.com/mediawiki/index.php?title=Modding&amp;diff=24731"/>
		<updated>2026-02-04T02:53:57Z</updated>

		<summary type="html">&lt;p&gt;Jamesp1989: /* Using a translation inside the game */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Modding is the act of modifying, adding or removing content and features. Mods are created by the community, and shared through the [https://steamcommunity.com/app/1169040/workshop/ Steam Workshop]. They can be anything like adding more items and monsters, adding a new language, changing the textures in the game, adding new features, tweaking balance and much more.&lt;br /&gt;
&lt;br /&gt;
Necesse mods are created using the Java programming language.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Installing and using mods ==&lt;br /&gt;
=== Steam Workshop ===&lt;br /&gt;
Modders usually share their mods on the [https://steamcommunity.com/app/1169040/workshop/ Steam Workshop]. If you subscribe to a mod, the next time you launch the game a mods button will appear in the main menu. In this menu you can see the mods you have installed, change their load order, enable or disable them.&lt;br /&gt;
=== Dedicated servers and local mods ===&lt;br /&gt;
For dedicated servers to have mods, they must find and download the mod jar file. Many modders give links to where they can be downloaded on the mods Workshop page. Once you have the jar file, you have to put it inside a mods folder, depending on your system. &amp;lt;br&amp;gt;&lt;br /&gt;
If the folder does not exist on your system, you can create one yourself.&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Note: ONLY the jar file is needed for the mod to be active, the rest of the files within the example mod are for gradle tasks to help make testing easier&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Windows:&#039;&#039;&#039; %APPDATA%/Necesse/mods/   &lt;br /&gt;
* &#039;&#039;&#039;Linux:&#039;&#039;&#039; ~/.config/Necesse/mods&lt;br /&gt;
* &#039;&#039;&#039;Mac:&#039;&#039;&#039; ~/Library/Application Support/Necesse/mods/&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Windows dedicated Server over steamcmd &#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Install your server as usual with steamcmd with the AppID 1169370.&lt;br /&gt;
&lt;br /&gt;
Create then in your server install directory a new folder mods&lt;br /&gt;
as example: c:\Servers\Necesse\mods&lt;br /&gt;
&lt;br /&gt;
Then you have to edit the server start parameters (in startserver-nogui.bat)&lt;br /&gt;
&lt;br /&gt;
default:&lt;br /&gt;
start jre\bin\java.exe -jar Server.jar -nogui %*&lt;br /&gt;
&lt;br /&gt;
edit in:&lt;br /&gt;
start jre\bin\java.exe -jar Server.jar -nogui -datadir .\data -mod .\mods&lt;br /&gt;
&lt;br /&gt;
Then copy your .jar mod files downloaded over the steam workshop as explained earlier in this thread into the mods folder. The server will recognize on startup the mods in the folder and loads them.&lt;br /&gt;
&lt;br /&gt;
== Texture/Resource packs ==&lt;br /&gt;
Texture packs are not officially supported, except through the modding system. However, it is still possible to overwrite existing textures inside the game. To do so, follow the steps:&lt;br /&gt;
&lt;br /&gt;
# Download the official textures, found on the [https://discord.gg/FAFgrKD Official Discord server], in a pinned message inside the wiki channel.&lt;br /&gt;
# Browse to the games install directory. You can do so by right-clicking the game in your Steam library -&amp;gt; Manage -&amp;gt; Browse local files.&lt;br /&gt;
# Extract the texture files into &amp;quot;&amp;lt;Necesse install directory&amp;gt;/res&amp;quot;. If the &amp;quot;res&amp;quot; folder does not exist, you have to create it yourself.&lt;br /&gt;
&lt;br /&gt;
The next time you launch the game, the textures will be loaded from those extracted files. This means you can edit or replace any of the files and that will then be loaded instead.&lt;br /&gt;
&lt;br /&gt;
== Creating mods ==&lt;br /&gt;
Necesse mods are created using the Java programming language. This place is not for you to learn Java, there are plenty of tutorials and resources on that out on the internet already.&lt;br /&gt;
&lt;br /&gt;
Mods are packaged inside a jar file for the game to load during runtime. When modding, it&#039;s a good idea to have a decompiler (included in most IDEs). The source code won&#039;t be released yet (if ever), and many topics are not explained thoroughly yet. This means you often have to rely on decompiling classes and checking out how they are done in the core game.&lt;br /&gt;
&lt;br /&gt;
[https://discord.gg/FAFgrKD The Official Discord Server] has a channel dedicated to modding where you can ask questions, get help and request new modding features for the game and all other things Necesse modding.&lt;br /&gt;
&lt;br /&gt;
=== New in v. 0.21.27 ===&lt;br /&gt;
&#039;&#039;If you are just starting out modding, you can skip this section.&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
In version 0.21.27 and forward, the game has changed the Java runtime environment it used. If you try to launch the game with the old runtime environment, you may run into crashes or other problems. You can download the runtime currently being used [https://adoptium.net/temurin/releases/?version=17 here]. To help with compatibility, the language level is still version 8. In IntelliJ, you can change your JDK and language level by going to File -&amp;gt; Project Structure... -&amp;gt; Project. Make sure that Gradle is also using the correct JDK by going to File -&amp;gt; Settings -&amp;gt; Build, Execution and Deployment -&amp;gt; Build Tools -&amp;gt; Gradle -&amp;gt; Gradle JVM. The example project has been updated to use this new Java and Gradle version.&lt;br /&gt;
&lt;br /&gt;
=== Getting started and example project ===&lt;br /&gt;
To get started on modding, there is an &#039;&#039;&#039;[https://github.com/DrFair/ExampleMod official example project you can download, found on Github].&#039;&#039;&#039; It includes basic stuff like adding items, tiles, objects, monsters, recipes and more. It also includes build tools using Gradle to easily compile and structure your mod so that it can be read and loaded by the game, as well as development tools like loading your in-development mod, so that you can upload it to the Steam Workshop when complete.&lt;br /&gt;
&lt;br /&gt;
=== Modding tools ===&lt;br /&gt;
* An integrated development environment (IDE). For example [https://www.jetbrains.com/idea/download Intellij IDEA Community] which is free.&lt;br /&gt;
* A Java development kit. The game is built using Adoptium Java17, which you can find [https://adoptium.net/temurin/releases/?version=17 here] but for compatibility reasons is still only using language level 8. If you are using the Intellij IDE, this is not needed as a JDK is already included in it. Make sure you are using language level 8 by going to File -&amp;gt; Project Structure... -&amp;gt; Language Level.&lt;br /&gt;
* An image editing tool, like pixel art editors [https://www.aseprite.org/ Aseprite] or [https://www.pyxeledit.com/ Pyxel Edit].&lt;br /&gt;
* An audio editing tool, like [https://www.audacityteam.org/ Audacity] or [https://www.reaper.fm/ REAPER].&lt;br /&gt;
&lt;br /&gt;
=== Setting up ===&lt;br /&gt;
If you have downloaded the example project, it can be loaded using your IDE and almost everything will already be set up for you. All you have to do is configure your &#039;&#039;build.gradle&#039;&#039; file with the correct mod info and the games install directory. Once done, it will prompt you to refresh the project.&lt;br /&gt;
&lt;br /&gt;
=== Running and testing your mod ===&lt;br /&gt;
[[File:Mod runClient Task.png|thumb|Image of where the gradle task can be found inside Intellij]]&lt;br /&gt;
To run your in-development mod, you will need to launch the game with &#039;&#039;-mod &amp;lt;folder path with your mod jar&amp;gt;&#039;&#039; option. This is already done for you if you are using the example project and run the &#039;&#039;runClient&#039;&#039; Gradle task. It can be found in the far-right toolbar inside Intellij (see image). Using this launch option will also allow you to upload your mod to Workshop once it is complete.&lt;br /&gt;
&lt;br /&gt;
==== Testing multiplayer ====&lt;br /&gt;
To test multiplayer, you can run one client with the &#039;&#039;runClient&#039;&#039; Gradle task, and another with the &#039;&#039;runDevClient&#039;&#039; Gradle task. One client should host the game, while the other should connect through the multiplayer menu. The hosted game should show up as a LAN server, or you can manually connect to it by using &amp;quot;localhost&amp;quot; as IP the address. The dev client will load into the game with a different authentication ID, allowing you to have 2 clients inside the same server.&lt;br /&gt;
&lt;br /&gt;
It&#039;s also important to test the dedicated server since it does not have access to the resources the clients load on startup. To do this, run the &#039;&#039;runServer&#039;&#039; Gradle task, and run your regular client at the same time. Same as above, you should then be able to see the game inside the multiplayer menu as a LAN server, or you can manually connect to it by using &amp;quot;localhost&amp;quot; as IP the address.&lt;br /&gt;
&lt;br /&gt;
=== Mod info file ===&lt;br /&gt;
Note: If you are using the example mod, you can skip this section as it is generated for you using the values you set inside the &#039;&#039;build.gradle&#039;&#039; file.&lt;br /&gt;
&lt;br /&gt;
Every mod must have a &#039;&#039;mod.info&#039;&#039; file in their jar&#039;s top path. The file structure is custom, but very similar to JSON. It&#039;s used throughout the game&#039;s saved files.&lt;br /&gt;
The file must have these fields:&lt;br /&gt;
* &#039;&#039;&#039;id&#039;&#039;&#039; - The unique ID of your mod. Must be all lowercase and cannot use special characters.&lt;br /&gt;
* &#039;&#039;&#039;name&#039;&#039;&#039; - The display name of your mod.&lt;br /&gt;
* &#039;&#039;&#039;version&#039;&#039;&#039; - The version of your mod.&lt;br /&gt;
* &#039;&#039;&#039;gameVersion&#039;&#039;&#039; - The target game version of your mod.&lt;br /&gt;
* &#039;&#039;&#039;description&#039;&#039;&#039; - A short description of your mod.&lt;br /&gt;
* &#039;&#039;&#039;author&#039;&#039;&#039; - Your name&lt;br /&gt;
* &#039;&#039;&#039;dependencies&#039;&#039;&#039; (optional) - Your mods dependencies are formatted in their IDs and array. Like this: [exammple.mod, other.mod]&lt;br /&gt;
* &#039;&#039;&#039;optionalDependecies&#039;&#039;&#039; (optional) - Your mods optional dependencies. They are used together with your dependencies to automatically make a load order for mods.&lt;br /&gt;
* &#039;&#039;&#039;clientside&#039;&#039;&#039; (optional) - true/false, if your mod is client/server-side only. This makes it possible for clients to connect to servers without the server needing the mod and vice versa. Defaults to false.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important notes about your mod.info file:&#039;&#039;&#039;&lt;br /&gt;
# Your id should be unique to the mod and never change between versions. A good example for id is &amp;quot;&amp;lt;your name&amp;gt;.&amp;lt;mod name&amp;gt;&amp;quot;.&lt;br /&gt;
# Avoid special characters that might inflict with the format, like commas, quotes, etc. This will probably be changed later, and you’ll be able to escape characters, just like in Java.&lt;br /&gt;
&lt;br /&gt;
Example of a mod.info file:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
   id = fair.examplemod,&lt;br /&gt;
   name = Example Mod,&lt;br /&gt;
   version = 1.0,&lt;br /&gt;
   gameVersion = 1.1.1,&lt;br /&gt;
   description = Just an example mod,&lt;br /&gt;
   author = Fair&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Mod entry class ===&lt;br /&gt;
Your mod needs an entry class. This is where the game loads your mod from and calls initialization methods. Create a class with the @ModEntry annotation to tell the game that&#039;s where your mod starts.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important notes about your @ModEntry class:&#039;&#039;&#039;&lt;br /&gt;
# Make sure your mod only has one @ModEntry annotation. The game will stop looking for more when found one.&lt;br /&gt;
# Make sure the class does NOT have a constructor.&lt;br /&gt;
&lt;br /&gt;
Example for your mod entry class:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=Java&amp;gt;&lt;br /&gt;
import necesse.engine.modLoader.annotations.ModEntry;&lt;br /&gt;
&lt;br /&gt;
@ModEntry&lt;br /&gt;
public class ExampleMod {&lt;br /&gt;
&lt;br /&gt;
    public void init() {&lt;br /&gt;
        System.out.println(&amp;quot;Hello world from my example mod!&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
The game will look for specific methods within your @ModEntry class. Here&#039;s a description of them:&lt;br /&gt;
&lt;br /&gt;
==== public void preInit() ====&lt;br /&gt;
This method is called before loading of the core game. It should only be used on rare occasions. If you are not sure about it, don&#039;t use it.&lt;br /&gt;
&lt;br /&gt;
==== public void init() ====&lt;br /&gt;
This method is called after the core game has been loaded. Here you should register your own tiles, objects, items, mobs and so on.&lt;br /&gt;
&lt;br /&gt;
The general order in which you should register your mod objects to avoid issues are (not forced):&lt;br /&gt;
# Tiles&lt;br /&gt;
# Objects&lt;br /&gt;
# Biomes&lt;br /&gt;
# Buffs&lt;br /&gt;
# Global ingredients&lt;br /&gt;
# Recipe techs&lt;br /&gt;
# Items&lt;br /&gt;
# Enchantments&lt;br /&gt;
# Mobs&lt;br /&gt;
# Pickup entities and projectiles&lt;br /&gt;
# Level, world events, level data and settlers&lt;br /&gt;
# Containers&lt;br /&gt;
# World generators&lt;br /&gt;
# Packets&lt;br /&gt;
# Quests&lt;br /&gt;
# Other&lt;br /&gt;
&lt;br /&gt;
==== public void initResources() ====&lt;br /&gt;
This method is called only on the client and should load any extra resources your mod uses that the game doesn&#039;t automatically load.&lt;br /&gt;
&lt;br /&gt;
The resources will be loaded from a resource folder. You can read more about this in a later section.&lt;br /&gt;
&lt;br /&gt;
Example: Assign a texture:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Java&amp;quot; inline=1&amp;gt;GameTexture texture = GameTexture.fromFile(&amp;quot;path/to/file&amp;quot;)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
If you have a texture at resources/texture.png you can load it using &amp;lt;syntaxhighlight lang=&amp;quot;Java&amp;quot; inline=1&amp;gt;GameTexture.fromFile(&amp;quot;texture&amp;quot;)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
All sound (.ogg) files need to be placed in resources/sound folder and can be loaded using&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Java&amp;quot; inline=1&amp;gt;GameSound.fromFile(&amp;quot;path/to/file&amp;quot;)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For example, a song placed in resources/sound/music/MySong.ogg would be loaded as &amp;lt;syntaxhighlight lang=&amp;quot;Java&amp;quot; inline=1&amp;gt;GameSound.fromFile(&amp;quot;music/MySong&amp;quot;)&amp;lt;/syntaxhighlight&amp;gt;, ommiting resources/sound&lt;br /&gt;
&lt;br /&gt;
For information on music paths to override music, look at &amp;lt;syntaxhighlight lang=&amp;quot;Java&amp;quot; inline=1&amp;gt;MusicRegistry.registerCore&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== public void postInit() ====&lt;br /&gt;
This method is called after the game is done loading all its core, mods and resources.&lt;br /&gt;
&lt;br /&gt;
This is where you should register recipes, create or modify loot tables and spawn tables and register chat commands.&lt;br /&gt;
&lt;br /&gt;
==== public void dispose() ====&lt;br /&gt;
This method is called when the game closes. If you have anything that needs to be disposed, that the game doesn&#039;t already dispose on it&#039;s own, do it here.&lt;br /&gt;
&lt;br /&gt;
Things like textured loaded using &amp;lt;syntaxhighlight lang=&amp;quot;Java&amp;quot; inline=1&amp;gt;GameTexture.fromFile(...)&amp;lt;/syntaxhighlight&amp;gt; and sounds are automatically disposed.&lt;br /&gt;
&lt;br /&gt;
=== Building your mod ===&lt;br /&gt;
If you are using the example project, a lot of this is already done for you. Simply run the &#039;&#039;buildModJar&#039;&#039; Gradle task, and it will generate the jar inside the ./build/jar folder.&lt;br /&gt;
&lt;br /&gt;
For the game to recognize your jar, it has to follow a specific structure:&lt;br /&gt;
;ExampleMod.jar&lt;br /&gt;
: ↳ resources&lt;br /&gt;
:: ↳ Your resource files&lt;br /&gt;
: ↳ Java class files&lt;br /&gt;
: ↳ mod.info file&lt;br /&gt;
&lt;br /&gt;
=== Uploading your mod ===&lt;br /&gt;
[[File:Upload mod.png|thumb|Image of the upload button when mod is loaded from development]]&lt;br /&gt;
To upload your mod to the Steam workshop, a few conditions have to be met:&lt;br /&gt;
* Must be enabled&lt;br /&gt;
* Must have a preview.png file in the resources folder&lt;br /&gt;
* Must be loaded through the -mod launch option (this is done automatically in the example project when running the &#039;&#039;runClient&#039;&#039; Gradle task. You can find more info about this under the beginning of the setting up section).&lt;br /&gt;
When all of these conditions are met, a button to upload your mod will appear when you select it inside the main menu mods screen. Click this and it will walk you through uploading to workshop. When you first upload, the mod will be hidden and only you will be able to see it. You can change this when you are ready to launch on your mods workshop page.&lt;br /&gt;
&lt;br /&gt;
=== Localization ===&lt;br /&gt;
Localization files are needed to give your tiles, objects, items, mobs and other things names. The files should be placed inside the resources/locale folder, and be named the same as the language they are using. Example: en.lang for the english translation.&lt;br /&gt;
&lt;br /&gt;
You can also see how the localization file is structured inside the example mod project.&lt;br /&gt;
&lt;br /&gt;
==== The file structure ====&lt;br /&gt;
The file is divided up into categories and keys. If your item has the localization &#039;&#039;item.exampleitem&#039;&#039;, it means that it&#039;s under the &#039;&#039;item&#039;&#039; category and has the key &#039;&#039;exampleitem&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
The language file is read line by line in order. If one line is a category change, all the next keys will be under that category. Here&#039;s an example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
[mycategory]&lt;br /&gt;
mykey=Text&lt;br /&gt;
otherkey=Other text&lt;br /&gt;
&lt;br /&gt;
[newcategory]&lt;br /&gt;
differentkey=Different text&lt;br /&gt;
&lt;br /&gt;
[item]&lt;br /&gt;
exampleitem=Example item&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Translations can have replacements that can be done in runtime. To add a replacement key in your translation, add a &amp;lt;key&amp;gt; somewhere. The key can be anything like &amp;lt;name&amp;gt;, &amp;lt;number&amp;gt; etc. Example: &amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot; inline=1&amp;gt;mobhealth=Mob health: &amp;lt;health&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Using a translation inside the game ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Java&amp;quot; inline=1&amp;gt;Localization.translate(category, key)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Java&amp;quot; inline=1&amp;gt;Localization.translate(category, key, replaceKey1, replaceString1, replaceKey2, replaceString2, ...)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A lot of places also use the GameMessage class. This is essentially a localizable string, by using LocalMessage which extends GameMessage. Goes the same as above:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Java&amp;quot; inline=1&amp;gt;new LocalMessage(category, key, replaceKey1, replaceString1, replaceKey2, replaceString2, ...)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you don&#039;t want to use a translation, you can also just give it a static string with &amp;lt;syntaxhighlight lang=&amp;quot;Java&amp;quot; inline=1&amp;gt;new StaticMessage(string...)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Resources ===&lt;br /&gt;
For the game to load your resources, they have to be placed inside a resources folder in your mod jar.&lt;br /&gt;
&lt;br /&gt;
Using this, it is also possible to overwrite existing ingame textures by placing another texture at the exact same path as the core game ones. In the Discord server, there is a wiki channel with a pinned message where the core textures can be downloaded and used for modding and this wiki.&lt;br /&gt;
&lt;br /&gt;
This also means that your resource files can get overwritten by other mods, so try and keep your file names unique.&lt;br /&gt;
&lt;br /&gt;
Resource loading happens automatically for any files in the resources folder. But some things will look at specific subfolders to load their textures. Examples:&lt;br /&gt;
* &#039;&#039;&#039;Items&#039;&#039;&#039; - items/&amp;lt;item stringiD&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Buffs&#039;&#039;&#039; - buffs/&amp;lt;buff stringiD&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Biomes&#039;&#039;&#039; - biomes/&amp;lt;biome stringiD&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Projectiles&#039;&#039;&#039; - projectiles/&amp;lt;projectile stringiD&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== More documentation ==&lt;br /&gt;
Until more documentation gets migrated and added to this wiki, you can use the old documentation here: [https://docs.google.com/document/u/1/d/e/2PACX-1vTexy0ZwJmztm6KhvwUCpSbgdNFV5hxUOr_6rSiCyqvjlj80Sj28Alenodq6AbOfnKaWoj-zv0iziyL/pub Published Google docs file]&lt;br /&gt;
[[Modding Snippets]] Has examples of other modders coding work that can be used to help you out.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Accessing Necesse Java files ==&lt;br /&gt;
[[File:Decompile1.png|thumb|Decompile1]]&lt;br /&gt;
[[File:Decompile2.png|thumb|Decompile2]]&lt;br /&gt;
[[File:Decompile3.png|thumb|Decompile3]]&lt;br /&gt;
[[File:Decompile4.png|thumb|Decompile4]]&lt;br /&gt;
using the IDE mentioned in [[Modding#Modding_tools|Modding Tools]], you can decompile java files and take a peek at the core game values.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{stub|reason = Need to reformat this section}}&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Note: Java may need to be installed for this process&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
You probably need to have Java installed.(external links not allowed) &amp;lt;br&amp;gt;&lt;br /&gt;
Download and install the Windows x64 .msi file&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Rough Transcript from Discord User Snoobinoob, to be refined:&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Open up IntelliJ IDEA and create a new Java project wherever&amp;lt;br&amp;gt;&lt;br /&gt;
File &amp;gt; New &amp;gt; Project...&amp;lt;br&amp;gt;&lt;br /&gt;
Can leave all settings as is&amp;lt;br&amp;gt;&lt;br /&gt;
Once the project is created, open up the project structure&amp;lt;br&amp;gt;&lt;br /&gt;
File &amp;gt; Project Structure... (Ctrl+Alt+Shift+S)&amp;lt;br&amp;gt;&lt;br /&gt;
select &amp;quot;Modules&amp;quot; from the left navigaiton pane&amp;lt;br&amp;gt;&lt;br /&gt;
Click the dependencies tab on the top-right-ish (Decompile1)&amp;lt;br&amp;gt;&lt;br /&gt;
Click the + icon to add a new module and choose &amp;quot;JARs or Directories&amp;quot; (Decompile2)&amp;lt;br&amp;gt;&lt;br /&gt;
Browse to the steam files location of Necesse.jar&amp;lt;br&amp;gt;&lt;br /&gt;
Should be something like: C:\Program Files (x86)\Steam\steamapps\common\Necesse\Necesse.jar&amp;lt;br&amp;gt;&lt;br /&gt;
Should see this (or similar) after clicking the +, choosing JARs or Directories, and browsing to the Necesse.jar location (Decompile3)&amp;lt;br&amp;gt;&lt;br /&gt;
Click OK, and you should now see Necesse.jar in the list of dependencies in the previous Modules window&amp;lt;br&amp;gt;&lt;br /&gt;
Click OK again to close the project structure window&amp;lt;br&amp;gt;&lt;br /&gt;
Necesse.jar should now be visible in External Libraries (Decompile4)&amp;lt;br&amp;gt;&lt;br /&gt;
Everything should now be set up, so you can search via the Navigate &amp;gt; Search Everywhere menu option&amp;lt;br&amp;gt;&lt;br /&gt;
Exactly what to search is up to you, and not always the most obvious&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jamesp1989</name></author>
	</entry>
	<entry>
		<id>https://necessewiki.com/mediawiki/index.php?title=Modding&amp;diff=24730</id>
		<title>Modding</title>
		<link rel="alternate" type="text/html" href="https://necessewiki.com/mediawiki/index.php?title=Modding&amp;diff=24730"/>
		<updated>2026-02-04T02:50:38Z</updated>

		<summary type="html">&lt;p&gt;Jamesp1989: /* The file structure */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Modding is the act of modifying, adding or removing content and features. Mods are created by the community, and shared through the [https://steamcommunity.com/app/1169040/workshop/ Steam Workshop]. They can be anything like adding more items and monsters, adding a new language, changing the textures in the game, adding new features, tweaking balance and much more.&lt;br /&gt;
&lt;br /&gt;
Necesse mods are created using the Java programming language.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Installing and using mods ==&lt;br /&gt;
=== Steam Workshop ===&lt;br /&gt;
Modders usually share their mods on the [https://steamcommunity.com/app/1169040/workshop/ Steam Workshop]. If you subscribe to a mod, the next time you launch the game a mods button will appear in the main menu. In this menu you can see the mods you have installed, change their load order, enable or disable them.&lt;br /&gt;
=== Dedicated servers and local mods ===&lt;br /&gt;
For dedicated servers to have mods, they must find and download the mod jar file. Many modders give links to where they can be downloaded on the mods Workshop page. Once you have the jar file, you have to put it inside a mods folder, depending on your system. &amp;lt;br&amp;gt;&lt;br /&gt;
If the folder does not exist on your system, you can create one yourself.&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Note: ONLY the jar file is needed for the mod to be active, the rest of the files within the example mod are for gradle tasks to help make testing easier&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Windows:&#039;&#039;&#039; %APPDATA%/Necesse/mods/   &lt;br /&gt;
* &#039;&#039;&#039;Linux:&#039;&#039;&#039; ~/.config/Necesse/mods&lt;br /&gt;
* &#039;&#039;&#039;Mac:&#039;&#039;&#039; ~/Library/Application Support/Necesse/mods/&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Windows dedicated Server over steamcmd &#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Install your server as usual with steamcmd with the AppID 1169370.&lt;br /&gt;
&lt;br /&gt;
Create then in your server install directory a new folder mods&lt;br /&gt;
as example: c:\Servers\Necesse\mods&lt;br /&gt;
&lt;br /&gt;
Then you have to edit the server start parameters (in startserver-nogui.bat)&lt;br /&gt;
&lt;br /&gt;
default:&lt;br /&gt;
start jre\bin\java.exe -jar Server.jar -nogui %*&lt;br /&gt;
&lt;br /&gt;
edit in:&lt;br /&gt;
start jre\bin\java.exe -jar Server.jar -nogui -datadir .\data -mod .\mods&lt;br /&gt;
&lt;br /&gt;
Then copy your .jar mod files downloaded over the steam workshop as explained earlier in this thread into the mods folder. The server will recognize on startup the mods in the folder and loads them.&lt;br /&gt;
&lt;br /&gt;
== Texture/Resource packs ==&lt;br /&gt;
Texture packs are not officially supported, except through the modding system. However, it is still possible to overwrite existing textures inside the game. To do so, follow the steps:&lt;br /&gt;
&lt;br /&gt;
# Download the official textures, found on the [https://discord.gg/FAFgrKD Official Discord server], in a pinned message inside the wiki channel.&lt;br /&gt;
# Browse to the games install directory. You can do so by right-clicking the game in your Steam library -&amp;gt; Manage -&amp;gt; Browse local files.&lt;br /&gt;
# Extract the texture files into &amp;quot;&amp;lt;Necesse install directory&amp;gt;/res&amp;quot;. If the &amp;quot;res&amp;quot; folder does not exist, you have to create it yourself.&lt;br /&gt;
&lt;br /&gt;
The next time you launch the game, the textures will be loaded from those extracted files. This means you can edit or replace any of the files and that will then be loaded instead.&lt;br /&gt;
&lt;br /&gt;
== Creating mods ==&lt;br /&gt;
Necesse mods are created using the Java programming language. This place is not for you to learn Java, there are plenty of tutorials and resources on that out on the internet already.&lt;br /&gt;
&lt;br /&gt;
Mods are packaged inside a jar file for the game to load during runtime. When modding, it&#039;s a good idea to have a decompiler (included in most IDEs). The source code won&#039;t be released yet (if ever), and many topics are not explained thoroughly yet. This means you often have to rely on decompiling classes and checking out how they are done in the core game.&lt;br /&gt;
&lt;br /&gt;
[https://discord.gg/FAFgrKD The Official Discord Server] has a channel dedicated to modding where you can ask questions, get help and request new modding features for the game and all other things Necesse modding.&lt;br /&gt;
&lt;br /&gt;
=== New in v. 0.21.27 ===&lt;br /&gt;
&#039;&#039;If you are just starting out modding, you can skip this section.&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
In version 0.21.27 and forward, the game has changed the Java runtime environment it used. If you try to launch the game with the old runtime environment, you may run into crashes or other problems. You can download the runtime currently being used [https://adoptium.net/temurin/releases/?version=17 here]. To help with compatibility, the language level is still version 8. In IntelliJ, you can change your JDK and language level by going to File -&amp;gt; Project Structure... -&amp;gt; Project. Make sure that Gradle is also using the correct JDK by going to File -&amp;gt; Settings -&amp;gt; Build, Execution and Deployment -&amp;gt; Build Tools -&amp;gt; Gradle -&amp;gt; Gradle JVM. The example project has been updated to use this new Java and Gradle version.&lt;br /&gt;
&lt;br /&gt;
=== Getting started and example project ===&lt;br /&gt;
To get started on modding, there is an &#039;&#039;&#039;[https://github.com/DrFair/ExampleMod official example project you can download, found on Github].&#039;&#039;&#039; It includes basic stuff like adding items, tiles, objects, monsters, recipes and more. It also includes build tools using Gradle to easily compile and structure your mod so that it can be read and loaded by the game, as well as development tools like loading your in-development mod, so that you can upload it to the Steam Workshop when complete.&lt;br /&gt;
&lt;br /&gt;
=== Modding tools ===&lt;br /&gt;
* An integrated development environment (IDE). For example [https://www.jetbrains.com/idea/download Intellij IDEA Community] which is free.&lt;br /&gt;
* A Java development kit. The game is built using Adoptium Java17, which you can find [https://adoptium.net/temurin/releases/?version=17 here] but for compatibility reasons is still only using language level 8. If you are using the Intellij IDE, this is not needed as a JDK is already included in it. Make sure you are using language level 8 by going to File -&amp;gt; Project Structure... -&amp;gt; Language Level.&lt;br /&gt;
* An image editing tool, like pixel art editors [https://www.aseprite.org/ Aseprite] or [https://www.pyxeledit.com/ Pyxel Edit].&lt;br /&gt;
* An audio editing tool, like [https://www.audacityteam.org/ Audacity] or [https://www.reaper.fm/ REAPER].&lt;br /&gt;
&lt;br /&gt;
=== Setting up ===&lt;br /&gt;
If you have downloaded the example project, it can be loaded using your IDE and almost everything will already be set up for you. All you have to do is configure your &#039;&#039;build.gradle&#039;&#039; file with the correct mod info and the games install directory. Once done, it will prompt you to refresh the project.&lt;br /&gt;
&lt;br /&gt;
=== Running and testing your mod ===&lt;br /&gt;
[[File:Mod runClient Task.png|thumb|Image of where the gradle task can be found inside Intellij]]&lt;br /&gt;
To run your in-development mod, you will need to launch the game with &#039;&#039;-mod &amp;lt;folder path with your mod jar&amp;gt;&#039;&#039; option. This is already done for you if you are using the example project and run the &#039;&#039;runClient&#039;&#039; Gradle task. It can be found in the far-right toolbar inside Intellij (see image). Using this launch option will also allow you to upload your mod to Workshop once it is complete.&lt;br /&gt;
&lt;br /&gt;
==== Testing multiplayer ====&lt;br /&gt;
To test multiplayer, you can run one client with the &#039;&#039;runClient&#039;&#039; Gradle task, and another with the &#039;&#039;runDevClient&#039;&#039; Gradle task. One client should host the game, while the other should connect through the multiplayer menu. The hosted game should show up as a LAN server, or you can manually connect to it by using &amp;quot;localhost&amp;quot; as IP the address. The dev client will load into the game with a different authentication ID, allowing you to have 2 clients inside the same server.&lt;br /&gt;
&lt;br /&gt;
It&#039;s also important to test the dedicated server since it does not have access to the resources the clients load on startup. To do this, run the &#039;&#039;runServer&#039;&#039; Gradle task, and run your regular client at the same time. Same as above, you should then be able to see the game inside the multiplayer menu as a LAN server, or you can manually connect to it by using &amp;quot;localhost&amp;quot; as IP the address.&lt;br /&gt;
&lt;br /&gt;
=== Mod info file ===&lt;br /&gt;
Note: If you are using the example mod, you can skip this section as it is generated for you using the values you set inside the &#039;&#039;build.gradle&#039;&#039; file.&lt;br /&gt;
&lt;br /&gt;
Every mod must have a &#039;&#039;mod.info&#039;&#039; file in their jar&#039;s top path. The file structure is custom, but very similar to JSON. It&#039;s used throughout the game&#039;s saved files.&lt;br /&gt;
The file must have these fields:&lt;br /&gt;
* &#039;&#039;&#039;id&#039;&#039;&#039; - The unique ID of your mod. Must be all lowercase and cannot use special characters.&lt;br /&gt;
* &#039;&#039;&#039;name&#039;&#039;&#039; - The display name of your mod.&lt;br /&gt;
* &#039;&#039;&#039;version&#039;&#039;&#039; - The version of your mod.&lt;br /&gt;
* &#039;&#039;&#039;gameVersion&#039;&#039;&#039; - The target game version of your mod.&lt;br /&gt;
* &#039;&#039;&#039;description&#039;&#039;&#039; - A short description of your mod.&lt;br /&gt;
* &#039;&#039;&#039;author&#039;&#039;&#039; - Your name&lt;br /&gt;
* &#039;&#039;&#039;dependencies&#039;&#039;&#039; (optional) - Your mods dependencies are formatted in their IDs and array. Like this: [exammple.mod, other.mod]&lt;br /&gt;
* &#039;&#039;&#039;optionalDependecies&#039;&#039;&#039; (optional) - Your mods optional dependencies. They are used together with your dependencies to automatically make a load order for mods.&lt;br /&gt;
* &#039;&#039;&#039;clientside&#039;&#039;&#039; (optional) - true/false, if your mod is client/server-side only. This makes it possible for clients to connect to servers without the server needing the mod and vice versa. Defaults to false.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important notes about your mod.info file:&#039;&#039;&#039;&lt;br /&gt;
# Your id should be unique to the mod and never change between versions. A good example for id is &amp;quot;&amp;lt;your name&amp;gt;.&amp;lt;mod name&amp;gt;&amp;quot;.&lt;br /&gt;
# Avoid special characters that might inflict with the format, like commas, quotes, etc. This will probably be changed later, and you’ll be able to escape characters, just like in Java.&lt;br /&gt;
&lt;br /&gt;
Example of a mod.info file:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
   id = fair.examplemod,&lt;br /&gt;
   name = Example Mod,&lt;br /&gt;
   version = 1.0,&lt;br /&gt;
   gameVersion = 1.1.1,&lt;br /&gt;
   description = Just an example mod,&lt;br /&gt;
   author = Fair&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Mod entry class ===&lt;br /&gt;
Your mod needs an entry class. This is where the game loads your mod from and calls initialization methods. Create a class with the @ModEntry annotation to tell the game that&#039;s where your mod starts.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important notes about your @ModEntry class:&#039;&#039;&#039;&lt;br /&gt;
# Make sure your mod only has one @ModEntry annotation. The game will stop looking for more when found one.&lt;br /&gt;
# Make sure the class does NOT have a constructor.&lt;br /&gt;
&lt;br /&gt;
Example for your mod entry class:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=Java&amp;gt;&lt;br /&gt;
import necesse.engine.modLoader.annotations.ModEntry;&lt;br /&gt;
&lt;br /&gt;
@ModEntry&lt;br /&gt;
public class ExampleMod {&lt;br /&gt;
&lt;br /&gt;
    public void init() {&lt;br /&gt;
        System.out.println(&amp;quot;Hello world from my example mod!&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
The game will look for specific methods within your @ModEntry class. Here&#039;s a description of them:&lt;br /&gt;
&lt;br /&gt;
==== public void preInit() ====&lt;br /&gt;
This method is called before loading of the core game. It should only be used on rare occasions. If you are not sure about it, don&#039;t use it.&lt;br /&gt;
&lt;br /&gt;
==== public void init() ====&lt;br /&gt;
This method is called after the core game has been loaded. Here you should register your own tiles, objects, items, mobs and so on.&lt;br /&gt;
&lt;br /&gt;
The general order in which you should register your mod objects to avoid issues are (not forced):&lt;br /&gt;
# Tiles&lt;br /&gt;
# Objects&lt;br /&gt;
# Biomes&lt;br /&gt;
# Buffs&lt;br /&gt;
# Global ingredients&lt;br /&gt;
# Recipe techs&lt;br /&gt;
# Items&lt;br /&gt;
# Enchantments&lt;br /&gt;
# Mobs&lt;br /&gt;
# Pickup entities and projectiles&lt;br /&gt;
# Level, world events, level data and settlers&lt;br /&gt;
# Containers&lt;br /&gt;
# World generators&lt;br /&gt;
# Packets&lt;br /&gt;
# Quests&lt;br /&gt;
# Other&lt;br /&gt;
&lt;br /&gt;
==== public void initResources() ====&lt;br /&gt;
This method is called only on the client and should load any extra resources your mod uses that the game doesn&#039;t automatically load.&lt;br /&gt;
&lt;br /&gt;
The resources will be loaded from a resource folder. You can read more about this in a later section.&lt;br /&gt;
&lt;br /&gt;
Example: Assign a texture:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Java&amp;quot; inline=1&amp;gt;GameTexture texture = GameTexture.fromFile(&amp;quot;path/to/file&amp;quot;)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
If you have a texture at resources/texture.png you can load it using &amp;lt;syntaxhighlight lang=&amp;quot;Java&amp;quot; inline=1&amp;gt;GameTexture.fromFile(&amp;quot;texture&amp;quot;)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
All sound (.ogg) files need to be placed in resources/sound folder and can be loaded using&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Java&amp;quot; inline=1&amp;gt;GameSound.fromFile(&amp;quot;path/to/file&amp;quot;)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For example, a song placed in resources/sound/music/MySong.ogg would be loaded as &amp;lt;syntaxhighlight lang=&amp;quot;Java&amp;quot; inline=1&amp;gt;GameSound.fromFile(&amp;quot;music/MySong&amp;quot;)&amp;lt;/syntaxhighlight&amp;gt;, ommiting resources/sound&lt;br /&gt;
&lt;br /&gt;
For information on music paths to override music, look at &amp;lt;syntaxhighlight lang=&amp;quot;Java&amp;quot; inline=1&amp;gt;MusicRegistry.registerCore&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== public void postInit() ====&lt;br /&gt;
This method is called after the game is done loading all its core, mods and resources.&lt;br /&gt;
&lt;br /&gt;
This is where you should register recipes, create or modify loot tables and spawn tables and register chat commands.&lt;br /&gt;
&lt;br /&gt;
==== public void dispose() ====&lt;br /&gt;
This method is called when the game closes. If you have anything that needs to be disposed, that the game doesn&#039;t already dispose on it&#039;s own, do it here.&lt;br /&gt;
&lt;br /&gt;
Things like textured loaded using &amp;lt;syntaxhighlight lang=&amp;quot;Java&amp;quot; inline=1&amp;gt;GameTexture.fromFile(...)&amp;lt;/syntaxhighlight&amp;gt; and sounds are automatically disposed.&lt;br /&gt;
&lt;br /&gt;
=== Building your mod ===&lt;br /&gt;
If you are using the example project, a lot of this is already done for you. Simply run the &#039;&#039;buildModJar&#039;&#039; Gradle task, and it will generate the jar inside the ./build/jar folder.&lt;br /&gt;
&lt;br /&gt;
For the game to recognize your jar, it has to follow a specific structure:&lt;br /&gt;
;ExampleMod.jar&lt;br /&gt;
: ↳ resources&lt;br /&gt;
:: ↳ Your resource files&lt;br /&gt;
: ↳ Java class files&lt;br /&gt;
: ↳ mod.info file&lt;br /&gt;
&lt;br /&gt;
=== Uploading your mod ===&lt;br /&gt;
[[File:Upload mod.png|thumb|Image of the upload button when mod is loaded from development]]&lt;br /&gt;
To upload your mod to the Steam workshop, a few conditions have to be met:&lt;br /&gt;
* Must be enabled&lt;br /&gt;
* Must have a preview.png file in the resources folder&lt;br /&gt;
* Must be loaded through the -mod launch option (this is done automatically in the example project when running the &#039;&#039;runClient&#039;&#039; Gradle task. You can find more info about this under the beginning of the setting up section).&lt;br /&gt;
When all of these conditions are met, a button to upload your mod will appear when you select it inside the main menu mods screen. Click this and it will walk you through uploading to workshop. When you first upload, the mod will be hidden and only you will be able to see it. You can change this when you are ready to launch on your mods workshop page.&lt;br /&gt;
&lt;br /&gt;
=== Localization ===&lt;br /&gt;
Localization files are needed to give your tiles, objects, items, mobs and other things names. The files should be placed inside the resources/locale folder, and be named the same as the language they are using. Example: en.lang for the english translation.&lt;br /&gt;
&lt;br /&gt;
You can also see how the localization file is structured inside the example mod project.&lt;br /&gt;
&lt;br /&gt;
==== The file structure ====&lt;br /&gt;
The file is divided up into categories and keys. If your item has the localization &#039;&#039;item.exampleitem&#039;&#039;, it means that it&#039;s under the &#039;&#039;item&#039;&#039; category and has the key &#039;&#039;exampleitem&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
The language file is read line by line in order. If one line is a category change, all the next keys will be under that category. Here&#039;s an example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
[mycategory]&lt;br /&gt;
mykey=Text&lt;br /&gt;
otherkey=Other text&lt;br /&gt;
&lt;br /&gt;
[newcategory]&lt;br /&gt;
differentkey=Different text&lt;br /&gt;
&lt;br /&gt;
[item]&lt;br /&gt;
exampleitem=Example item&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Translations can have replacements that can be done in runtime. To add a replacement key in your translation, add a &amp;lt;key&amp;gt; somewhere. The key can be anything like &amp;lt;name&amp;gt;, &amp;lt;number&amp;gt; etc. Example: &amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot; inline=1&amp;gt;mobhealth=Mob health: &amp;lt;health&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Using a translation inside the game ====&lt;br /&gt;
&amp;lt;code&amp;gt;Localization.translate(category, key)&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;Localization.translate(category, key, replaceKey1, replaceString1, replaceKey2, replaceString2, ...)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A lot of places also use the GameMessage class. This is essentially a localizable string, by using LocalMessage which extends GameMessage. Goes the same as above:&lt;br /&gt;
&amp;lt;code&amp;gt;new LocalMessage(category, key, replaceKey1, replaceString1, replaceKey2, replaceString2, ...)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you don&#039;t want to use a translation, you can also just give it a static string with &amp;lt;code&amp;gt;new StaticMessage(string...)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Resources ===&lt;br /&gt;
For the game to load your resources, they have to be placed inside a resources folder in your mod jar.&lt;br /&gt;
&lt;br /&gt;
Using this, it is also possible to overwrite existing ingame textures by placing another texture at the exact same path as the core game ones. In the Discord server, there is a wiki channel with a pinned message where the core textures can be downloaded and used for modding and this wiki.&lt;br /&gt;
&lt;br /&gt;
This also means that your resource files can get overwritten by other mods, so try and keep your file names unique.&lt;br /&gt;
&lt;br /&gt;
Resource loading happens automatically for any files in the resources folder. But some things will look at specific subfolders to load their textures. Examples:&lt;br /&gt;
* &#039;&#039;&#039;Items&#039;&#039;&#039; - items/&amp;lt;item stringiD&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Buffs&#039;&#039;&#039; - buffs/&amp;lt;buff stringiD&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Biomes&#039;&#039;&#039; - biomes/&amp;lt;biome stringiD&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Projectiles&#039;&#039;&#039; - projectiles/&amp;lt;projectile stringiD&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== More documentation ==&lt;br /&gt;
Until more documentation gets migrated and added to this wiki, you can use the old documentation here: [https://docs.google.com/document/u/1/d/e/2PACX-1vTexy0ZwJmztm6KhvwUCpSbgdNFV5hxUOr_6rSiCyqvjlj80Sj28Alenodq6AbOfnKaWoj-zv0iziyL/pub Published Google docs file]&lt;br /&gt;
[[Modding Snippets]] Has examples of other modders coding work that can be used to help you out.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Accessing Necesse Java files ==&lt;br /&gt;
[[File:Decompile1.png|thumb|Decompile1]]&lt;br /&gt;
[[File:Decompile2.png|thumb|Decompile2]]&lt;br /&gt;
[[File:Decompile3.png|thumb|Decompile3]]&lt;br /&gt;
[[File:Decompile4.png|thumb|Decompile4]]&lt;br /&gt;
using the IDE mentioned in [[Modding#Modding_tools|Modding Tools]], you can decompile java files and take a peek at the core game values.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{stub|reason = Need to reformat this section}}&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Note: Java may need to be installed for this process&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
You probably need to have Java installed.(external links not allowed) &amp;lt;br&amp;gt;&lt;br /&gt;
Download and install the Windows x64 .msi file&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Rough Transcript from Discord User Snoobinoob, to be refined:&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Open up IntelliJ IDEA and create a new Java project wherever&amp;lt;br&amp;gt;&lt;br /&gt;
File &amp;gt; New &amp;gt; Project...&amp;lt;br&amp;gt;&lt;br /&gt;
Can leave all settings as is&amp;lt;br&amp;gt;&lt;br /&gt;
Once the project is created, open up the project structure&amp;lt;br&amp;gt;&lt;br /&gt;
File &amp;gt; Project Structure... (Ctrl+Alt+Shift+S)&amp;lt;br&amp;gt;&lt;br /&gt;
select &amp;quot;Modules&amp;quot; from the left navigaiton pane&amp;lt;br&amp;gt;&lt;br /&gt;
Click the dependencies tab on the top-right-ish (Decompile1)&amp;lt;br&amp;gt;&lt;br /&gt;
Click the + icon to add a new module and choose &amp;quot;JARs or Directories&amp;quot; (Decompile2)&amp;lt;br&amp;gt;&lt;br /&gt;
Browse to the steam files location of Necesse.jar&amp;lt;br&amp;gt;&lt;br /&gt;
Should be something like: C:\Program Files (x86)\Steam\steamapps\common\Necesse\Necesse.jar&amp;lt;br&amp;gt;&lt;br /&gt;
Should see this (or similar) after clicking the +, choosing JARs or Directories, and browsing to the Necesse.jar location (Decompile3)&amp;lt;br&amp;gt;&lt;br /&gt;
Click OK, and you should now see Necesse.jar in the list of dependencies in the previous Modules window&amp;lt;br&amp;gt;&lt;br /&gt;
Click OK again to close the project structure window&amp;lt;br&amp;gt;&lt;br /&gt;
Necesse.jar should now be visible in External Libraries (Decompile4)&amp;lt;br&amp;gt;&lt;br /&gt;
Everything should now be set up, so you can search via the Navigate &amp;gt; Search Everywhere menu option&amp;lt;br&amp;gt;&lt;br /&gt;
Exactly what to search is up to you, and not always the most obvious&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jamesp1989</name></author>
	</entry>
	<entry>
		<id>https://necessewiki.com/mediawiki/index.php?title=Modding&amp;diff=24729</id>
		<title>Modding</title>
		<link rel="alternate" type="text/html" href="https://necessewiki.com/mediawiki/index.php?title=Modding&amp;diff=24729"/>
		<updated>2026-02-04T02:49:43Z</updated>

		<summary type="html">&lt;p&gt;Jamesp1989: /* public void dispose() */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Modding is the act of modifying, adding or removing content and features. Mods are created by the community, and shared through the [https://steamcommunity.com/app/1169040/workshop/ Steam Workshop]. They can be anything like adding more items and monsters, adding a new language, changing the textures in the game, adding new features, tweaking balance and much more.&lt;br /&gt;
&lt;br /&gt;
Necesse mods are created using the Java programming language.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Installing and using mods ==&lt;br /&gt;
=== Steam Workshop ===&lt;br /&gt;
Modders usually share their mods on the [https://steamcommunity.com/app/1169040/workshop/ Steam Workshop]. If you subscribe to a mod, the next time you launch the game a mods button will appear in the main menu. In this menu you can see the mods you have installed, change their load order, enable or disable them.&lt;br /&gt;
=== Dedicated servers and local mods ===&lt;br /&gt;
For dedicated servers to have mods, they must find and download the mod jar file. Many modders give links to where they can be downloaded on the mods Workshop page. Once you have the jar file, you have to put it inside a mods folder, depending on your system. &amp;lt;br&amp;gt;&lt;br /&gt;
If the folder does not exist on your system, you can create one yourself.&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Note: ONLY the jar file is needed for the mod to be active, the rest of the files within the example mod are for gradle tasks to help make testing easier&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Windows:&#039;&#039;&#039; %APPDATA%/Necesse/mods/   &lt;br /&gt;
* &#039;&#039;&#039;Linux:&#039;&#039;&#039; ~/.config/Necesse/mods&lt;br /&gt;
* &#039;&#039;&#039;Mac:&#039;&#039;&#039; ~/Library/Application Support/Necesse/mods/&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Windows dedicated Server over steamcmd &#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Install your server as usual with steamcmd with the AppID 1169370.&lt;br /&gt;
&lt;br /&gt;
Create then in your server install directory a new folder mods&lt;br /&gt;
as example: c:\Servers\Necesse\mods&lt;br /&gt;
&lt;br /&gt;
Then you have to edit the server start parameters (in startserver-nogui.bat)&lt;br /&gt;
&lt;br /&gt;
default:&lt;br /&gt;
start jre\bin\java.exe -jar Server.jar -nogui %*&lt;br /&gt;
&lt;br /&gt;
edit in:&lt;br /&gt;
start jre\bin\java.exe -jar Server.jar -nogui -datadir .\data -mod .\mods&lt;br /&gt;
&lt;br /&gt;
Then copy your .jar mod files downloaded over the steam workshop as explained earlier in this thread into the mods folder. The server will recognize on startup the mods in the folder and loads them.&lt;br /&gt;
&lt;br /&gt;
== Texture/Resource packs ==&lt;br /&gt;
Texture packs are not officially supported, except through the modding system. However, it is still possible to overwrite existing textures inside the game. To do so, follow the steps:&lt;br /&gt;
&lt;br /&gt;
# Download the official textures, found on the [https://discord.gg/FAFgrKD Official Discord server], in a pinned message inside the wiki channel.&lt;br /&gt;
# Browse to the games install directory. You can do so by right-clicking the game in your Steam library -&amp;gt; Manage -&amp;gt; Browse local files.&lt;br /&gt;
# Extract the texture files into &amp;quot;&amp;lt;Necesse install directory&amp;gt;/res&amp;quot;. If the &amp;quot;res&amp;quot; folder does not exist, you have to create it yourself.&lt;br /&gt;
&lt;br /&gt;
The next time you launch the game, the textures will be loaded from those extracted files. This means you can edit or replace any of the files and that will then be loaded instead.&lt;br /&gt;
&lt;br /&gt;
== Creating mods ==&lt;br /&gt;
Necesse mods are created using the Java programming language. This place is not for you to learn Java, there are plenty of tutorials and resources on that out on the internet already.&lt;br /&gt;
&lt;br /&gt;
Mods are packaged inside a jar file for the game to load during runtime. When modding, it&#039;s a good idea to have a decompiler (included in most IDEs). The source code won&#039;t be released yet (if ever), and many topics are not explained thoroughly yet. This means you often have to rely on decompiling classes and checking out how they are done in the core game.&lt;br /&gt;
&lt;br /&gt;
[https://discord.gg/FAFgrKD The Official Discord Server] has a channel dedicated to modding where you can ask questions, get help and request new modding features for the game and all other things Necesse modding.&lt;br /&gt;
&lt;br /&gt;
=== New in v. 0.21.27 ===&lt;br /&gt;
&#039;&#039;If you are just starting out modding, you can skip this section.&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
In version 0.21.27 and forward, the game has changed the Java runtime environment it used. If you try to launch the game with the old runtime environment, you may run into crashes or other problems. You can download the runtime currently being used [https://adoptium.net/temurin/releases/?version=17 here]. To help with compatibility, the language level is still version 8. In IntelliJ, you can change your JDK and language level by going to File -&amp;gt; Project Structure... -&amp;gt; Project. Make sure that Gradle is also using the correct JDK by going to File -&amp;gt; Settings -&amp;gt; Build, Execution and Deployment -&amp;gt; Build Tools -&amp;gt; Gradle -&amp;gt; Gradle JVM. The example project has been updated to use this new Java and Gradle version.&lt;br /&gt;
&lt;br /&gt;
=== Getting started and example project ===&lt;br /&gt;
To get started on modding, there is an &#039;&#039;&#039;[https://github.com/DrFair/ExampleMod official example project you can download, found on Github].&#039;&#039;&#039; It includes basic stuff like adding items, tiles, objects, monsters, recipes and more. It also includes build tools using Gradle to easily compile and structure your mod so that it can be read and loaded by the game, as well as development tools like loading your in-development mod, so that you can upload it to the Steam Workshop when complete.&lt;br /&gt;
&lt;br /&gt;
=== Modding tools ===&lt;br /&gt;
* An integrated development environment (IDE). For example [https://www.jetbrains.com/idea/download Intellij IDEA Community] which is free.&lt;br /&gt;
* A Java development kit. The game is built using Adoptium Java17, which you can find [https://adoptium.net/temurin/releases/?version=17 here] but for compatibility reasons is still only using language level 8. If you are using the Intellij IDE, this is not needed as a JDK is already included in it. Make sure you are using language level 8 by going to File -&amp;gt; Project Structure... -&amp;gt; Language Level.&lt;br /&gt;
* An image editing tool, like pixel art editors [https://www.aseprite.org/ Aseprite] or [https://www.pyxeledit.com/ Pyxel Edit].&lt;br /&gt;
* An audio editing tool, like [https://www.audacityteam.org/ Audacity] or [https://www.reaper.fm/ REAPER].&lt;br /&gt;
&lt;br /&gt;
=== Setting up ===&lt;br /&gt;
If you have downloaded the example project, it can be loaded using your IDE and almost everything will already be set up for you. All you have to do is configure your &#039;&#039;build.gradle&#039;&#039; file with the correct mod info and the games install directory. Once done, it will prompt you to refresh the project.&lt;br /&gt;
&lt;br /&gt;
=== Running and testing your mod ===&lt;br /&gt;
[[File:Mod runClient Task.png|thumb|Image of where the gradle task can be found inside Intellij]]&lt;br /&gt;
To run your in-development mod, you will need to launch the game with &#039;&#039;-mod &amp;lt;folder path with your mod jar&amp;gt;&#039;&#039; option. This is already done for you if you are using the example project and run the &#039;&#039;runClient&#039;&#039; Gradle task. It can be found in the far-right toolbar inside Intellij (see image). Using this launch option will also allow you to upload your mod to Workshop once it is complete.&lt;br /&gt;
&lt;br /&gt;
==== Testing multiplayer ====&lt;br /&gt;
To test multiplayer, you can run one client with the &#039;&#039;runClient&#039;&#039; Gradle task, and another with the &#039;&#039;runDevClient&#039;&#039; Gradle task. One client should host the game, while the other should connect through the multiplayer menu. The hosted game should show up as a LAN server, or you can manually connect to it by using &amp;quot;localhost&amp;quot; as IP the address. The dev client will load into the game with a different authentication ID, allowing you to have 2 clients inside the same server.&lt;br /&gt;
&lt;br /&gt;
It&#039;s also important to test the dedicated server since it does not have access to the resources the clients load on startup. To do this, run the &#039;&#039;runServer&#039;&#039; Gradle task, and run your regular client at the same time. Same as above, you should then be able to see the game inside the multiplayer menu as a LAN server, or you can manually connect to it by using &amp;quot;localhost&amp;quot; as IP the address.&lt;br /&gt;
&lt;br /&gt;
=== Mod info file ===&lt;br /&gt;
Note: If you are using the example mod, you can skip this section as it is generated for you using the values you set inside the &#039;&#039;build.gradle&#039;&#039; file.&lt;br /&gt;
&lt;br /&gt;
Every mod must have a &#039;&#039;mod.info&#039;&#039; file in their jar&#039;s top path. The file structure is custom, but very similar to JSON. It&#039;s used throughout the game&#039;s saved files.&lt;br /&gt;
The file must have these fields:&lt;br /&gt;
* &#039;&#039;&#039;id&#039;&#039;&#039; - The unique ID of your mod. Must be all lowercase and cannot use special characters.&lt;br /&gt;
* &#039;&#039;&#039;name&#039;&#039;&#039; - The display name of your mod.&lt;br /&gt;
* &#039;&#039;&#039;version&#039;&#039;&#039; - The version of your mod.&lt;br /&gt;
* &#039;&#039;&#039;gameVersion&#039;&#039;&#039; - The target game version of your mod.&lt;br /&gt;
* &#039;&#039;&#039;description&#039;&#039;&#039; - A short description of your mod.&lt;br /&gt;
* &#039;&#039;&#039;author&#039;&#039;&#039; - Your name&lt;br /&gt;
* &#039;&#039;&#039;dependencies&#039;&#039;&#039; (optional) - Your mods dependencies are formatted in their IDs and array. Like this: [exammple.mod, other.mod]&lt;br /&gt;
* &#039;&#039;&#039;optionalDependecies&#039;&#039;&#039; (optional) - Your mods optional dependencies. They are used together with your dependencies to automatically make a load order for mods.&lt;br /&gt;
* &#039;&#039;&#039;clientside&#039;&#039;&#039; (optional) - true/false, if your mod is client/server-side only. This makes it possible for clients to connect to servers without the server needing the mod and vice versa. Defaults to false.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important notes about your mod.info file:&#039;&#039;&#039;&lt;br /&gt;
# Your id should be unique to the mod and never change between versions. A good example for id is &amp;quot;&amp;lt;your name&amp;gt;.&amp;lt;mod name&amp;gt;&amp;quot;.&lt;br /&gt;
# Avoid special characters that might inflict with the format, like commas, quotes, etc. This will probably be changed later, and you’ll be able to escape characters, just like in Java.&lt;br /&gt;
&lt;br /&gt;
Example of a mod.info file:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
   id = fair.examplemod,&lt;br /&gt;
   name = Example Mod,&lt;br /&gt;
   version = 1.0,&lt;br /&gt;
   gameVersion = 1.1.1,&lt;br /&gt;
   description = Just an example mod,&lt;br /&gt;
   author = Fair&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Mod entry class ===&lt;br /&gt;
Your mod needs an entry class. This is where the game loads your mod from and calls initialization methods. Create a class with the @ModEntry annotation to tell the game that&#039;s where your mod starts.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important notes about your @ModEntry class:&#039;&#039;&#039;&lt;br /&gt;
# Make sure your mod only has one @ModEntry annotation. The game will stop looking for more when found one.&lt;br /&gt;
# Make sure the class does NOT have a constructor.&lt;br /&gt;
&lt;br /&gt;
Example for your mod entry class:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=Java&amp;gt;&lt;br /&gt;
import necesse.engine.modLoader.annotations.ModEntry;&lt;br /&gt;
&lt;br /&gt;
@ModEntry&lt;br /&gt;
public class ExampleMod {&lt;br /&gt;
&lt;br /&gt;
    public void init() {&lt;br /&gt;
        System.out.println(&amp;quot;Hello world from my example mod!&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
The game will look for specific methods within your @ModEntry class. Here&#039;s a description of them:&lt;br /&gt;
&lt;br /&gt;
==== public void preInit() ====&lt;br /&gt;
This method is called before loading of the core game. It should only be used on rare occasions. If you are not sure about it, don&#039;t use it.&lt;br /&gt;
&lt;br /&gt;
==== public void init() ====&lt;br /&gt;
This method is called after the core game has been loaded. Here you should register your own tiles, objects, items, mobs and so on.&lt;br /&gt;
&lt;br /&gt;
The general order in which you should register your mod objects to avoid issues are (not forced):&lt;br /&gt;
# Tiles&lt;br /&gt;
# Objects&lt;br /&gt;
# Biomes&lt;br /&gt;
# Buffs&lt;br /&gt;
# Global ingredients&lt;br /&gt;
# Recipe techs&lt;br /&gt;
# Items&lt;br /&gt;
# Enchantments&lt;br /&gt;
# Mobs&lt;br /&gt;
# Pickup entities and projectiles&lt;br /&gt;
# Level, world events, level data and settlers&lt;br /&gt;
# Containers&lt;br /&gt;
# World generators&lt;br /&gt;
# Packets&lt;br /&gt;
# Quests&lt;br /&gt;
# Other&lt;br /&gt;
&lt;br /&gt;
==== public void initResources() ====&lt;br /&gt;
This method is called only on the client and should load any extra resources your mod uses that the game doesn&#039;t automatically load.&lt;br /&gt;
&lt;br /&gt;
The resources will be loaded from a resource folder. You can read more about this in a later section.&lt;br /&gt;
&lt;br /&gt;
Example: Assign a texture:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Java&amp;quot; inline=1&amp;gt;GameTexture texture = GameTexture.fromFile(&amp;quot;path/to/file&amp;quot;)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
If you have a texture at resources/texture.png you can load it using &amp;lt;syntaxhighlight lang=&amp;quot;Java&amp;quot; inline=1&amp;gt;GameTexture.fromFile(&amp;quot;texture&amp;quot;)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
All sound (.ogg) files need to be placed in resources/sound folder and can be loaded using&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Java&amp;quot; inline=1&amp;gt;GameSound.fromFile(&amp;quot;path/to/file&amp;quot;)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For example, a song placed in resources/sound/music/MySong.ogg would be loaded as &amp;lt;syntaxhighlight lang=&amp;quot;Java&amp;quot; inline=1&amp;gt;GameSound.fromFile(&amp;quot;music/MySong&amp;quot;)&amp;lt;/syntaxhighlight&amp;gt;, ommiting resources/sound&lt;br /&gt;
&lt;br /&gt;
For information on music paths to override music, look at &amp;lt;syntaxhighlight lang=&amp;quot;Java&amp;quot; inline=1&amp;gt;MusicRegistry.registerCore&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== public void postInit() ====&lt;br /&gt;
This method is called after the game is done loading all its core, mods and resources.&lt;br /&gt;
&lt;br /&gt;
This is where you should register recipes, create or modify loot tables and spawn tables and register chat commands.&lt;br /&gt;
&lt;br /&gt;
==== public void dispose() ====&lt;br /&gt;
This method is called when the game closes. If you have anything that needs to be disposed, that the game doesn&#039;t already dispose on it&#039;s own, do it here.&lt;br /&gt;
&lt;br /&gt;
Things like textured loaded using &amp;lt;syntaxhighlight lang=&amp;quot;Java&amp;quot; inline=1&amp;gt;GameTexture.fromFile(...)&amp;lt;/syntaxhighlight&amp;gt; and sounds are automatically disposed.&lt;br /&gt;
&lt;br /&gt;
=== Building your mod ===&lt;br /&gt;
If you are using the example project, a lot of this is already done for you. Simply run the &#039;&#039;buildModJar&#039;&#039; Gradle task, and it will generate the jar inside the ./build/jar folder.&lt;br /&gt;
&lt;br /&gt;
For the game to recognize your jar, it has to follow a specific structure:&lt;br /&gt;
;ExampleMod.jar&lt;br /&gt;
: ↳ resources&lt;br /&gt;
:: ↳ Your resource files&lt;br /&gt;
: ↳ Java class files&lt;br /&gt;
: ↳ mod.info file&lt;br /&gt;
&lt;br /&gt;
=== Uploading your mod ===&lt;br /&gt;
[[File:Upload mod.png|thumb|Image of the upload button when mod is loaded from development]]&lt;br /&gt;
To upload your mod to the Steam workshop, a few conditions have to be met:&lt;br /&gt;
* Must be enabled&lt;br /&gt;
* Must have a preview.png file in the resources folder&lt;br /&gt;
* Must be loaded through the -mod launch option (this is done automatically in the example project when running the &#039;&#039;runClient&#039;&#039; Gradle task. You can find more info about this under the beginning of the setting up section).&lt;br /&gt;
When all of these conditions are met, a button to upload your mod will appear when you select it inside the main menu mods screen. Click this and it will walk you through uploading to workshop. When you first upload, the mod will be hidden and only you will be able to see it. You can change this when you are ready to launch on your mods workshop page.&lt;br /&gt;
&lt;br /&gt;
=== Localization ===&lt;br /&gt;
Localization files are needed to give your tiles, objects, items, mobs and other things names. The files should be placed inside the resources/locale folder, and be named the same as the language they are using. Example: en.lang for the english translation.&lt;br /&gt;
&lt;br /&gt;
You can also see how the localization file is structured inside the example mod project.&lt;br /&gt;
&lt;br /&gt;
==== The file structure ====&lt;br /&gt;
The file is divided up into categories and keys. If your item has the localization &#039;&#039;item.exampleitem&#039;&#039;, it means that it&#039;s under the &#039;&#039;item&#039;&#039; category and has the key &#039;&#039;exampleitem&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
The language file is read line by line in order. If one line is a category change, all the next keys will be under that category. Here&#039;s an example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
[mycategory]&lt;br /&gt;
mykey=Text&lt;br /&gt;
otherkey=Other text&lt;br /&gt;
&lt;br /&gt;
[newcategory]&lt;br /&gt;
differentkey=Different text&lt;br /&gt;
&lt;br /&gt;
[item]&lt;br /&gt;
exampleitem=Example item&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Translations can have replacements that can be done in runtime. To add a replacement key in your translation, add a &amp;lt;key&amp;gt; somewhere. The key can be anything like &amp;lt;name&amp;gt;, &amp;lt;number&amp;gt; etc. Example: &amp;lt;code&amp;gt;mobhealth=Mob health: &amp;lt;health&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Using a translation inside the game ====&lt;br /&gt;
&amp;lt;code&amp;gt;Localization.translate(category, key)&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;Localization.translate(category, key, replaceKey1, replaceString1, replaceKey2, replaceString2, ...)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A lot of places also use the GameMessage class. This is essentially a localizable string, by using LocalMessage which extends GameMessage. Goes the same as above:&lt;br /&gt;
&amp;lt;code&amp;gt;new LocalMessage(category, key, replaceKey1, replaceString1, replaceKey2, replaceString2, ...)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you don&#039;t want to use a translation, you can also just give it a static string with &amp;lt;code&amp;gt;new StaticMessage(string...)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Resources ===&lt;br /&gt;
For the game to load your resources, they have to be placed inside a resources folder in your mod jar.&lt;br /&gt;
&lt;br /&gt;
Using this, it is also possible to overwrite existing ingame textures by placing another texture at the exact same path as the core game ones. In the Discord server, there is a wiki channel with a pinned message where the core textures can be downloaded and used for modding and this wiki.&lt;br /&gt;
&lt;br /&gt;
This also means that your resource files can get overwritten by other mods, so try and keep your file names unique.&lt;br /&gt;
&lt;br /&gt;
Resource loading happens automatically for any files in the resources folder. But some things will look at specific subfolders to load their textures. Examples:&lt;br /&gt;
* &#039;&#039;&#039;Items&#039;&#039;&#039; - items/&amp;lt;item stringiD&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Buffs&#039;&#039;&#039; - buffs/&amp;lt;buff stringiD&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Biomes&#039;&#039;&#039; - biomes/&amp;lt;biome stringiD&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Projectiles&#039;&#039;&#039; - projectiles/&amp;lt;projectile stringiD&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== More documentation ==&lt;br /&gt;
Until more documentation gets migrated and added to this wiki, you can use the old documentation here: [https://docs.google.com/document/u/1/d/e/2PACX-1vTexy0ZwJmztm6KhvwUCpSbgdNFV5hxUOr_6rSiCyqvjlj80Sj28Alenodq6AbOfnKaWoj-zv0iziyL/pub Published Google docs file]&lt;br /&gt;
[[Modding Snippets]] Has examples of other modders coding work that can be used to help you out.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Accessing Necesse Java files ==&lt;br /&gt;
[[File:Decompile1.png|thumb|Decompile1]]&lt;br /&gt;
[[File:Decompile2.png|thumb|Decompile2]]&lt;br /&gt;
[[File:Decompile3.png|thumb|Decompile3]]&lt;br /&gt;
[[File:Decompile4.png|thumb|Decompile4]]&lt;br /&gt;
using the IDE mentioned in [[Modding#Modding_tools|Modding Tools]], you can decompile java files and take a peek at the core game values.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{stub|reason = Need to reformat this section}}&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Note: Java may need to be installed for this process&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
You probably need to have Java installed.(external links not allowed) &amp;lt;br&amp;gt;&lt;br /&gt;
Download and install the Windows x64 .msi file&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Rough Transcript from Discord User Snoobinoob, to be refined:&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Open up IntelliJ IDEA and create a new Java project wherever&amp;lt;br&amp;gt;&lt;br /&gt;
File &amp;gt; New &amp;gt; Project...&amp;lt;br&amp;gt;&lt;br /&gt;
Can leave all settings as is&amp;lt;br&amp;gt;&lt;br /&gt;
Once the project is created, open up the project structure&amp;lt;br&amp;gt;&lt;br /&gt;
File &amp;gt; Project Structure... (Ctrl+Alt+Shift+S)&amp;lt;br&amp;gt;&lt;br /&gt;
select &amp;quot;Modules&amp;quot; from the left navigaiton pane&amp;lt;br&amp;gt;&lt;br /&gt;
Click the dependencies tab on the top-right-ish (Decompile1)&amp;lt;br&amp;gt;&lt;br /&gt;
Click the + icon to add a new module and choose &amp;quot;JARs or Directories&amp;quot; (Decompile2)&amp;lt;br&amp;gt;&lt;br /&gt;
Browse to the steam files location of Necesse.jar&amp;lt;br&amp;gt;&lt;br /&gt;
Should be something like: C:\Program Files (x86)\Steam\steamapps\common\Necesse\Necesse.jar&amp;lt;br&amp;gt;&lt;br /&gt;
Should see this (or similar) after clicking the +, choosing JARs or Directories, and browsing to the Necesse.jar location (Decompile3)&amp;lt;br&amp;gt;&lt;br /&gt;
Click OK, and you should now see Necesse.jar in the list of dependencies in the previous Modules window&amp;lt;br&amp;gt;&lt;br /&gt;
Click OK again to close the project structure window&amp;lt;br&amp;gt;&lt;br /&gt;
Necesse.jar should now be visible in External Libraries (Decompile4)&amp;lt;br&amp;gt;&lt;br /&gt;
Everything should now be set up, so you can search via the Navigate &amp;gt; Search Everywhere menu option&amp;lt;br&amp;gt;&lt;br /&gt;
Exactly what to search is up to you, and not always the most obvious&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jamesp1989</name></author>
	</entry>
	<entry>
		<id>https://necessewiki.com/mediawiki/index.php?title=Modding&amp;diff=24728</id>
		<title>Modding</title>
		<link rel="alternate" type="text/html" href="https://necessewiki.com/mediawiki/index.php?title=Modding&amp;diff=24728"/>
		<updated>2026-02-04T02:47:54Z</updated>

		<summary type="html">&lt;p&gt;Jamesp1989: moved to syntax highlighter&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Modding is the act of modifying, adding or removing content and features. Mods are created by the community, and shared through the [https://steamcommunity.com/app/1169040/workshop/ Steam Workshop]. They can be anything like adding more items and monsters, adding a new language, changing the textures in the game, adding new features, tweaking balance and much more.&lt;br /&gt;
&lt;br /&gt;
Necesse mods are created using the Java programming language.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Installing and using mods ==&lt;br /&gt;
=== Steam Workshop ===&lt;br /&gt;
Modders usually share their mods on the [https://steamcommunity.com/app/1169040/workshop/ Steam Workshop]. If you subscribe to a mod, the next time you launch the game a mods button will appear in the main menu. In this menu you can see the mods you have installed, change their load order, enable or disable them.&lt;br /&gt;
=== Dedicated servers and local mods ===&lt;br /&gt;
For dedicated servers to have mods, they must find and download the mod jar file. Many modders give links to where they can be downloaded on the mods Workshop page. Once you have the jar file, you have to put it inside a mods folder, depending on your system. &amp;lt;br&amp;gt;&lt;br /&gt;
If the folder does not exist on your system, you can create one yourself.&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Note: ONLY the jar file is needed for the mod to be active, the rest of the files within the example mod are for gradle tasks to help make testing easier&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Windows:&#039;&#039;&#039; %APPDATA%/Necesse/mods/   &lt;br /&gt;
* &#039;&#039;&#039;Linux:&#039;&#039;&#039; ~/.config/Necesse/mods&lt;br /&gt;
* &#039;&#039;&#039;Mac:&#039;&#039;&#039; ~/Library/Application Support/Necesse/mods/&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Windows dedicated Server over steamcmd &#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Install your server as usual with steamcmd with the AppID 1169370.&lt;br /&gt;
&lt;br /&gt;
Create then in your server install directory a new folder mods&lt;br /&gt;
as example: c:\Servers\Necesse\mods&lt;br /&gt;
&lt;br /&gt;
Then you have to edit the server start parameters (in startserver-nogui.bat)&lt;br /&gt;
&lt;br /&gt;
default:&lt;br /&gt;
start jre\bin\java.exe -jar Server.jar -nogui %*&lt;br /&gt;
&lt;br /&gt;
edit in:&lt;br /&gt;
start jre\bin\java.exe -jar Server.jar -nogui -datadir .\data -mod .\mods&lt;br /&gt;
&lt;br /&gt;
Then copy your .jar mod files downloaded over the steam workshop as explained earlier in this thread into the mods folder. The server will recognize on startup the mods in the folder and loads them.&lt;br /&gt;
&lt;br /&gt;
== Texture/Resource packs ==&lt;br /&gt;
Texture packs are not officially supported, except through the modding system. However, it is still possible to overwrite existing textures inside the game. To do so, follow the steps:&lt;br /&gt;
&lt;br /&gt;
# Download the official textures, found on the [https://discord.gg/FAFgrKD Official Discord server], in a pinned message inside the wiki channel.&lt;br /&gt;
# Browse to the games install directory. You can do so by right-clicking the game in your Steam library -&amp;gt; Manage -&amp;gt; Browse local files.&lt;br /&gt;
# Extract the texture files into &amp;quot;&amp;lt;Necesse install directory&amp;gt;/res&amp;quot;. If the &amp;quot;res&amp;quot; folder does not exist, you have to create it yourself.&lt;br /&gt;
&lt;br /&gt;
The next time you launch the game, the textures will be loaded from those extracted files. This means you can edit or replace any of the files and that will then be loaded instead.&lt;br /&gt;
&lt;br /&gt;
== Creating mods ==&lt;br /&gt;
Necesse mods are created using the Java programming language. This place is not for you to learn Java, there are plenty of tutorials and resources on that out on the internet already.&lt;br /&gt;
&lt;br /&gt;
Mods are packaged inside a jar file for the game to load during runtime. When modding, it&#039;s a good idea to have a decompiler (included in most IDEs). The source code won&#039;t be released yet (if ever), and many topics are not explained thoroughly yet. This means you often have to rely on decompiling classes and checking out how they are done in the core game.&lt;br /&gt;
&lt;br /&gt;
[https://discord.gg/FAFgrKD The Official Discord Server] has a channel dedicated to modding where you can ask questions, get help and request new modding features for the game and all other things Necesse modding.&lt;br /&gt;
&lt;br /&gt;
=== New in v. 0.21.27 ===&lt;br /&gt;
&#039;&#039;If you are just starting out modding, you can skip this section.&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
In version 0.21.27 and forward, the game has changed the Java runtime environment it used. If you try to launch the game with the old runtime environment, you may run into crashes or other problems. You can download the runtime currently being used [https://adoptium.net/temurin/releases/?version=17 here]. To help with compatibility, the language level is still version 8. In IntelliJ, you can change your JDK and language level by going to File -&amp;gt; Project Structure... -&amp;gt; Project. Make sure that Gradle is also using the correct JDK by going to File -&amp;gt; Settings -&amp;gt; Build, Execution and Deployment -&amp;gt; Build Tools -&amp;gt; Gradle -&amp;gt; Gradle JVM. The example project has been updated to use this new Java and Gradle version.&lt;br /&gt;
&lt;br /&gt;
=== Getting started and example project ===&lt;br /&gt;
To get started on modding, there is an &#039;&#039;&#039;[https://github.com/DrFair/ExampleMod official example project you can download, found on Github].&#039;&#039;&#039; It includes basic stuff like adding items, tiles, objects, monsters, recipes and more. It also includes build tools using Gradle to easily compile and structure your mod so that it can be read and loaded by the game, as well as development tools like loading your in-development mod, so that you can upload it to the Steam Workshop when complete.&lt;br /&gt;
&lt;br /&gt;
=== Modding tools ===&lt;br /&gt;
* An integrated development environment (IDE). For example [https://www.jetbrains.com/idea/download Intellij IDEA Community] which is free.&lt;br /&gt;
* A Java development kit. The game is built using Adoptium Java17, which you can find [https://adoptium.net/temurin/releases/?version=17 here] but for compatibility reasons is still only using language level 8. If you are using the Intellij IDE, this is not needed as a JDK is already included in it. Make sure you are using language level 8 by going to File -&amp;gt; Project Structure... -&amp;gt; Language Level.&lt;br /&gt;
* An image editing tool, like pixel art editors [https://www.aseprite.org/ Aseprite] or [https://www.pyxeledit.com/ Pyxel Edit].&lt;br /&gt;
* An audio editing tool, like [https://www.audacityteam.org/ Audacity] or [https://www.reaper.fm/ REAPER].&lt;br /&gt;
&lt;br /&gt;
=== Setting up ===&lt;br /&gt;
If you have downloaded the example project, it can be loaded using your IDE and almost everything will already be set up for you. All you have to do is configure your &#039;&#039;build.gradle&#039;&#039; file with the correct mod info and the games install directory. Once done, it will prompt you to refresh the project.&lt;br /&gt;
&lt;br /&gt;
=== Running and testing your mod ===&lt;br /&gt;
[[File:Mod runClient Task.png|thumb|Image of where the gradle task can be found inside Intellij]]&lt;br /&gt;
To run your in-development mod, you will need to launch the game with &#039;&#039;-mod &amp;lt;folder path with your mod jar&amp;gt;&#039;&#039; option. This is already done for you if you are using the example project and run the &#039;&#039;runClient&#039;&#039; Gradle task. It can be found in the far-right toolbar inside Intellij (see image). Using this launch option will also allow you to upload your mod to Workshop once it is complete.&lt;br /&gt;
&lt;br /&gt;
==== Testing multiplayer ====&lt;br /&gt;
To test multiplayer, you can run one client with the &#039;&#039;runClient&#039;&#039; Gradle task, and another with the &#039;&#039;runDevClient&#039;&#039; Gradle task. One client should host the game, while the other should connect through the multiplayer menu. The hosted game should show up as a LAN server, or you can manually connect to it by using &amp;quot;localhost&amp;quot; as IP the address. The dev client will load into the game with a different authentication ID, allowing you to have 2 clients inside the same server.&lt;br /&gt;
&lt;br /&gt;
It&#039;s also important to test the dedicated server since it does not have access to the resources the clients load on startup. To do this, run the &#039;&#039;runServer&#039;&#039; Gradle task, and run your regular client at the same time. Same as above, you should then be able to see the game inside the multiplayer menu as a LAN server, or you can manually connect to it by using &amp;quot;localhost&amp;quot; as IP the address.&lt;br /&gt;
&lt;br /&gt;
=== Mod info file ===&lt;br /&gt;
Note: If you are using the example mod, you can skip this section as it is generated for you using the values you set inside the &#039;&#039;build.gradle&#039;&#039; file.&lt;br /&gt;
&lt;br /&gt;
Every mod must have a &#039;&#039;mod.info&#039;&#039; file in their jar&#039;s top path. The file structure is custom, but very similar to JSON. It&#039;s used throughout the game&#039;s saved files.&lt;br /&gt;
The file must have these fields:&lt;br /&gt;
* &#039;&#039;&#039;id&#039;&#039;&#039; - The unique ID of your mod. Must be all lowercase and cannot use special characters.&lt;br /&gt;
* &#039;&#039;&#039;name&#039;&#039;&#039; - The display name of your mod.&lt;br /&gt;
* &#039;&#039;&#039;version&#039;&#039;&#039; - The version of your mod.&lt;br /&gt;
* &#039;&#039;&#039;gameVersion&#039;&#039;&#039; - The target game version of your mod.&lt;br /&gt;
* &#039;&#039;&#039;description&#039;&#039;&#039; - A short description of your mod.&lt;br /&gt;
* &#039;&#039;&#039;author&#039;&#039;&#039; - Your name&lt;br /&gt;
* &#039;&#039;&#039;dependencies&#039;&#039;&#039; (optional) - Your mods dependencies are formatted in their IDs and array. Like this: [exammple.mod, other.mod]&lt;br /&gt;
* &#039;&#039;&#039;optionalDependecies&#039;&#039;&#039; (optional) - Your mods optional dependencies. They are used together with your dependencies to automatically make a load order for mods.&lt;br /&gt;
* &#039;&#039;&#039;clientside&#039;&#039;&#039; (optional) - true/false, if your mod is client/server-side only. This makes it possible for clients to connect to servers without the server needing the mod and vice versa. Defaults to false.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important notes about your mod.info file:&#039;&#039;&#039;&lt;br /&gt;
# Your id should be unique to the mod and never change between versions. A good example for id is &amp;quot;&amp;lt;your name&amp;gt;.&amp;lt;mod name&amp;gt;&amp;quot;.&lt;br /&gt;
# Avoid special characters that might inflict with the format, like commas, quotes, etc. This will probably be changed later, and you’ll be able to escape characters, just like in Java.&lt;br /&gt;
&lt;br /&gt;
Example of a mod.info file:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
   id = fair.examplemod,&lt;br /&gt;
   name = Example Mod,&lt;br /&gt;
   version = 1.0,&lt;br /&gt;
   gameVersion = 1.1.1,&lt;br /&gt;
   description = Just an example mod,&lt;br /&gt;
   author = Fair&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Mod entry class ===&lt;br /&gt;
Your mod needs an entry class. This is where the game loads your mod from and calls initialization methods. Create a class with the @ModEntry annotation to tell the game that&#039;s where your mod starts.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important notes about your @ModEntry class:&#039;&#039;&#039;&lt;br /&gt;
# Make sure your mod only has one @ModEntry annotation. The game will stop looking for more when found one.&lt;br /&gt;
# Make sure the class does NOT have a constructor.&lt;br /&gt;
&lt;br /&gt;
Example for your mod entry class:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=Java&amp;gt;&lt;br /&gt;
import necesse.engine.modLoader.annotations.ModEntry;&lt;br /&gt;
&lt;br /&gt;
@ModEntry&lt;br /&gt;
public class ExampleMod {&lt;br /&gt;
&lt;br /&gt;
    public void init() {&lt;br /&gt;
        System.out.println(&amp;quot;Hello world from my example mod!&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
The game will look for specific methods within your @ModEntry class. Here&#039;s a description of them:&lt;br /&gt;
&lt;br /&gt;
==== public void preInit() ====&lt;br /&gt;
This method is called before loading of the core game. It should only be used on rare occasions. If you are not sure about it, don&#039;t use it.&lt;br /&gt;
&lt;br /&gt;
==== public void init() ====&lt;br /&gt;
This method is called after the core game has been loaded. Here you should register your own tiles, objects, items, mobs and so on.&lt;br /&gt;
&lt;br /&gt;
The general order in which you should register your mod objects to avoid issues are (not forced):&lt;br /&gt;
# Tiles&lt;br /&gt;
# Objects&lt;br /&gt;
# Biomes&lt;br /&gt;
# Buffs&lt;br /&gt;
# Global ingredients&lt;br /&gt;
# Recipe techs&lt;br /&gt;
# Items&lt;br /&gt;
# Enchantments&lt;br /&gt;
# Mobs&lt;br /&gt;
# Pickup entities and projectiles&lt;br /&gt;
# Level, world events, level data and settlers&lt;br /&gt;
# Containers&lt;br /&gt;
# World generators&lt;br /&gt;
# Packets&lt;br /&gt;
# Quests&lt;br /&gt;
# Other&lt;br /&gt;
&lt;br /&gt;
==== public void initResources() ====&lt;br /&gt;
This method is called only on the client and should load any extra resources your mod uses that the game doesn&#039;t automatically load.&lt;br /&gt;
&lt;br /&gt;
The resources will be loaded from a resource folder. You can read more about this in a later section.&lt;br /&gt;
&lt;br /&gt;
Example: Assign a texture:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Java&amp;quot; inline=1&amp;gt;GameTexture texture = GameTexture.fromFile(&amp;quot;path/to/file&amp;quot;)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
If you have a texture at resources/texture.png you can load it using &amp;lt;syntaxhighlight lang=&amp;quot;Java&amp;quot; inline=1&amp;gt;GameTexture.fromFile(&amp;quot;texture&amp;quot;)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
All sound (.ogg) files need to be placed in resources/sound folder and can be loaded using&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Java&amp;quot; inline=1&amp;gt;GameSound.fromFile(&amp;quot;path/to/file&amp;quot;)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For example, a song placed in resources/sound/music/MySong.ogg would be loaded as &amp;lt;syntaxhighlight lang=&amp;quot;Java&amp;quot; inline=1&amp;gt;GameSound.fromFile(&amp;quot;music/MySong&amp;quot;)&amp;lt;/syntaxhighlight&amp;gt;, ommiting resources/sound&lt;br /&gt;
&lt;br /&gt;
For information on music paths to override music, look at &amp;lt;syntaxhighlight lang=&amp;quot;Java&amp;quot; inline=1&amp;gt;MusicRegistry.registerCore&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== public void postInit() ====&lt;br /&gt;
This method is called after the game is done loading all its core, mods and resources.&lt;br /&gt;
&lt;br /&gt;
This is where you should register recipes, create or modify loot tables and spawn tables and register chat commands.&lt;br /&gt;
&lt;br /&gt;
==== public void dispose() ====&lt;br /&gt;
This method is called when the game closes. If you have anything that needs to be disposed, that the game doesn&#039;t already dispose on it&#039;s own, do it here.&lt;br /&gt;
&lt;br /&gt;
Things like textured loaded using &amp;lt;code&amp;gt;GameTexture.fromFile(...)&amp;lt;/code&amp;gt; and sounds are automatically disposed.&lt;br /&gt;
&lt;br /&gt;
=== Building your mod ===&lt;br /&gt;
If you are using the example project, a lot of this is already done for you. Simply run the &#039;&#039;buildModJar&#039;&#039; Gradle task, and it will generate the jar inside the ./build/jar folder.&lt;br /&gt;
&lt;br /&gt;
For the game to recognize your jar, it has to follow a specific structure:&lt;br /&gt;
;ExampleMod.jar&lt;br /&gt;
: ↳ resources&lt;br /&gt;
:: ↳ Your resource files&lt;br /&gt;
: ↳ Java class files&lt;br /&gt;
: ↳ mod.info file&lt;br /&gt;
&lt;br /&gt;
=== Uploading your mod ===&lt;br /&gt;
[[File:Upload mod.png|thumb|Image of the upload button when mod is loaded from development]]&lt;br /&gt;
To upload your mod to the Steam workshop, a few conditions have to be met:&lt;br /&gt;
* Must be enabled&lt;br /&gt;
* Must have a preview.png file in the resources folder&lt;br /&gt;
* Must be loaded through the -mod launch option (this is done automatically in the example project when running the &#039;&#039;runClient&#039;&#039; Gradle task. You can find more info about this under the beginning of the setting up section).&lt;br /&gt;
When all of these conditions are met, a button to upload your mod will appear when you select it inside the main menu mods screen. Click this and it will walk you through uploading to workshop. When you first upload, the mod will be hidden and only you will be able to see it. You can change this when you are ready to launch on your mods workshop page.&lt;br /&gt;
&lt;br /&gt;
=== Localization ===&lt;br /&gt;
Localization files are needed to give your tiles, objects, items, mobs and other things names. The files should be placed inside the resources/locale folder, and be named the same as the language they are using. Example: en.lang for the english translation.&lt;br /&gt;
&lt;br /&gt;
You can also see how the localization file is structured inside the example mod project.&lt;br /&gt;
&lt;br /&gt;
==== The file structure ====&lt;br /&gt;
The file is divided up into categories and keys. If your item has the localization &#039;&#039;item.exampleitem&#039;&#039;, it means that it&#039;s under the &#039;&#039;item&#039;&#039; category and has the key &#039;&#039;exampleitem&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
The language file is read line by line in order. If one line is a category change, all the next keys will be under that category. Here&#039;s an example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
[mycategory]&lt;br /&gt;
mykey=Text&lt;br /&gt;
otherkey=Other text&lt;br /&gt;
&lt;br /&gt;
[newcategory]&lt;br /&gt;
differentkey=Different text&lt;br /&gt;
&lt;br /&gt;
[item]&lt;br /&gt;
exampleitem=Example item&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Translations can have replacements that can be done in runtime. To add a replacement key in your translation, add a &amp;lt;key&amp;gt; somewhere. The key can be anything like &amp;lt;name&amp;gt;, &amp;lt;number&amp;gt; etc. Example: &amp;lt;code&amp;gt;mobhealth=Mob health: &amp;lt;health&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Using a translation inside the game ====&lt;br /&gt;
&amp;lt;code&amp;gt;Localization.translate(category, key)&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;Localization.translate(category, key, replaceKey1, replaceString1, replaceKey2, replaceString2, ...)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A lot of places also use the GameMessage class. This is essentially a localizable string, by using LocalMessage which extends GameMessage. Goes the same as above:&lt;br /&gt;
&amp;lt;code&amp;gt;new LocalMessage(category, key, replaceKey1, replaceString1, replaceKey2, replaceString2, ...)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you don&#039;t want to use a translation, you can also just give it a static string with &amp;lt;code&amp;gt;new StaticMessage(string...)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Resources ===&lt;br /&gt;
For the game to load your resources, they have to be placed inside a resources folder in your mod jar.&lt;br /&gt;
&lt;br /&gt;
Using this, it is also possible to overwrite existing ingame textures by placing another texture at the exact same path as the core game ones. In the Discord server, there is a wiki channel with a pinned message where the core textures can be downloaded and used for modding and this wiki.&lt;br /&gt;
&lt;br /&gt;
This also means that your resource files can get overwritten by other mods, so try and keep your file names unique.&lt;br /&gt;
&lt;br /&gt;
Resource loading happens automatically for any files in the resources folder. But some things will look at specific subfolders to load their textures. Examples:&lt;br /&gt;
* &#039;&#039;&#039;Items&#039;&#039;&#039; - items/&amp;lt;item stringiD&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Buffs&#039;&#039;&#039; - buffs/&amp;lt;buff stringiD&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Biomes&#039;&#039;&#039; - biomes/&amp;lt;biome stringiD&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Projectiles&#039;&#039;&#039; - projectiles/&amp;lt;projectile stringiD&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== More documentation ==&lt;br /&gt;
Until more documentation gets migrated and added to this wiki, you can use the old documentation here: [https://docs.google.com/document/u/1/d/e/2PACX-1vTexy0ZwJmztm6KhvwUCpSbgdNFV5hxUOr_6rSiCyqvjlj80Sj28Alenodq6AbOfnKaWoj-zv0iziyL/pub Published Google docs file]&lt;br /&gt;
[[Modding Snippets]] Has examples of other modders coding work that can be used to help you out.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Accessing Necesse Java files ==&lt;br /&gt;
[[File:Decompile1.png|thumb|Decompile1]]&lt;br /&gt;
[[File:Decompile2.png|thumb|Decompile2]]&lt;br /&gt;
[[File:Decompile3.png|thumb|Decompile3]]&lt;br /&gt;
[[File:Decompile4.png|thumb|Decompile4]]&lt;br /&gt;
using the IDE mentioned in [[Modding#Modding_tools|Modding Tools]], you can decompile java files and take a peek at the core game values.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{stub|reason = Need to reformat this section}}&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Note: Java may need to be installed for this process&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
You probably need to have Java installed.(external links not allowed) &amp;lt;br&amp;gt;&lt;br /&gt;
Download and install the Windows x64 .msi file&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Rough Transcript from Discord User Snoobinoob, to be refined:&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Open up IntelliJ IDEA and create a new Java project wherever&amp;lt;br&amp;gt;&lt;br /&gt;
File &amp;gt; New &amp;gt; Project...&amp;lt;br&amp;gt;&lt;br /&gt;
Can leave all settings as is&amp;lt;br&amp;gt;&lt;br /&gt;
Once the project is created, open up the project structure&amp;lt;br&amp;gt;&lt;br /&gt;
File &amp;gt; Project Structure... (Ctrl+Alt+Shift+S)&amp;lt;br&amp;gt;&lt;br /&gt;
select &amp;quot;Modules&amp;quot; from the left navigaiton pane&amp;lt;br&amp;gt;&lt;br /&gt;
Click the dependencies tab on the top-right-ish (Decompile1)&amp;lt;br&amp;gt;&lt;br /&gt;
Click the + icon to add a new module and choose &amp;quot;JARs or Directories&amp;quot; (Decompile2)&amp;lt;br&amp;gt;&lt;br /&gt;
Browse to the steam files location of Necesse.jar&amp;lt;br&amp;gt;&lt;br /&gt;
Should be something like: C:\Program Files (x86)\Steam\steamapps\common\Necesse\Necesse.jar&amp;lt;br&amp;gt;&lt;br /&gt;
Should see this (or similar) after clicking the +, choosing JARs or Directories, and browsing to the Necesse.jar location (Decompile3)&amp;lt;br&amp;gt;&lt;br /&gt;
Click OK, and you should now see Necesse.jar in the list of dependencies in the previous Modules window&amp;lt;br&amp;gt;&lt;br /&gt;
Click OK again to close the project structure window&amp;lt;br&amp;gt;&lt;br /&gt;
Necesse.jar should now be visible in External Libraries (Decompile4)&amp;lt;br&amp;gt;&lt;br /&gt;
Everything should now be set up, so you can search via the Navigate &amp;gt; Search Everywhere menu option&amp;lt;br&amp;gt;&lt;br /&gt;
Exactly what to search is up to you, and not always the most obvious&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jamesp1989</name></author>
	</entry>
	<entry>
		<id>https://necessewiki.com/mediawiki/index.php?title=Modding&amp;diff=24727</id>
		<title>Modding</title>
		<link rel="alternate" type="text/html" href="https://necessewiki.com/mediawiki/index.php?title=Modding&amp;diff=24727"/>
		<updated>2026-02-04T02:43:48Z</updated>

		<summary type="html">&lt;p&gt;Jamesp1989: /* Mod info file */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Modding is the act of modifying, adding or removing content and features. Mods are created by the community, and shared through the [https://steamcommunity.com/app/1169040/workshop/ Steam Workshop]. They can be anything like adding more items and monsters, adding a new language, changing the textures in the game, adding new features, tweaking balance and much more.&lt;br /&gt;
&lt;br /&gt;
Necesse mods are created using the Java programming language.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Installing and using mods ==&lt;br /&gt;
=== Steam Workshop ===&lt;br /&gt;
Modders usually share their mods on the [https://steamcommunity.com/app/1169040/workshop/ Steam Workshop]. If you subscribe to a mod, the next time you launch the game a mods button will appear in the main menu. In this menu you can see the mods you have installed, change their load order, enable or disable them.&lt;br /&gt;
=== Dedicated servers and local mods ===&lt;br /&gt;
For dedicated servers to have mods, they must find and download the mod jar file. Many modders give links to where they can be downloaded on the mods Workshop page. Once you have the jar file, you have to put it inside a mods folder, depending on your system. &amp;lt;br&amp;gt;&lt;br /&gt;
If the folder does not exist on your system, you can create one yourself.&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Note: ONLY the jar file is needed for the mod to be active, the rest of the files within the example mod are for gradle tasks to help make testing easier&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Windows:&#039;&#039;&#039; %APPDATA%/Necesse/mods/   &lt;br /&gt;
* &#039;&#039;&#039;Linux:&#039;&#039;&#039; ~/.config/Necesse/mods&lt;br /&gt;
* &#039;&#039;&#039;Mac:&#039;&#039;&#039; ~/Library/Application Support/Necesse/mods/&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Windows dedicated Server over steamcmd &#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Install your server as usual with steamcmd with the AppID 1169370.&lt;br /&gt;
&lt;br /&gt;
Create then in your server install directory a new folder mods&lt;br /&gt;
as example: c:\Servers\Necesse\mods&lt;br /&gt;
&lt;br /&gt;
Then you have to edit the server start parameters (in startserver-nogui.bat)&lt;br /&gt;
&lt;br /&gt;
default:&lt;br /&gt;
start jre\bin\java.exe -jar Server.jar -nogui %*&lt;br /&gt;
&lt;br /&gt;
edit in:&lt;br /&gt;
start jre\bin\java.exe -jar Server.jar -nogui -datadir .\data -mod .\mods&lt;br /&gt;
&lt;br /&gt;
Then copy your .jar mod files downloaded over the steam workshop as explained earlier in this thread into the mods folder. The server will recognize on startup the mods in the folder and loads them.&lt;br /&gt;
&lt;br /&gt;
== Texture/Resource packs ==&lt;br /&gt;
Texture packs are not officially supported, except through the modding system. However, it is still possible to overwrite existing textures inside the game. To do so, follow the steps:&lt;br /&gt;
&lt;br /&gt;
# Download the official textures, found on the [https://discord.gg/FAFgrKD Official Discord server], in a pinned message inside the wiki channel.&lt;br /&gt;
# Browse to the games install directory. You can do so by right-clicking the game in your Steam library -&amp;gt; Manage -&amp;gt; Browse local files.&lt;br /&gt;
# Extract the texture files into &amp;quot;&amp;lt;Necesse install directory&amp;gt;/res&amp;quot;. If the &amp;quot;res&amp;quot; folder does not exist, you have to create it yourself.&lt;br /&gt;
&lt;br /&gt;
The next time you launch the game, the textures will be loaded from those extracted files. This means you can edit or replace any of the files and that will then be loaded instead.&lt;br /&gt;
&lt;br /&gt;
== Creating mods ==&lt;br /&gt;
Necesse mods are created using the Java programming language. This place is not for you to learn Java, there are plenty of tutorials and resources on that out on the internet already.&lt;br /&gt;
&lt;br /&gt;
Mods are packaged inside a jar file for the game to load during runtime. When modding, it&#039;s a good idea to have a decompiler (included in most IDEs). The source code won&#039;t be released yet (if ever), and many topics are not explained thoroughly yet. This means you often have to rely on decompiling classes and checking out how they are done in the core game.&lt;br /&gt;
&lt;br /&gt;
[https://discord.gg/FAFgrKD The Official Discord Server] has a channel dedicated to modding where you can ask questions, get help and request new modding features for the game and all other things Necesse modding.&lt;br /&gt;
&lt;br /&gt;
=== New in v. 0.21.27 ===&lt;br /&gt;
&#039;&#039;If you are just starting out modding, you can skip this section.&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
In version 0.21.27 and forward, the game has changed the Java runtime environment it used. If you try to launch the game with the old runtime environment, you may run into crashes or other problems. You can download the runtime currently being used [https://adoptium.net/temurin/releases/?version=17 here]. To help with compatibility, the language level is still version 8. In IntelliJ, you can change your JDK and language level by going to File -&amp;gt; Project Structure... -&amp;gt; Project. Make sure that Gradle is also using the correct JDK by going to File -&amp;gt; Settings -&amp;gt; Build, Execution and Deployment -&amp;gt; Build Tools -&amp;gt; Gradle -&amp;gt; Gradle JVM. The example project has been updated to use this new Java and Gradle version.&lt;br /&gt;
&lt;br /&gt;
=== Getting started and example project ===&lt;br /&gt;
To get started on modding, there is an &#039;&#039;&#039;[https://github.com/DrFair/ExampleMod official example project you can download, found on Github].&#039;&#039;&#039; It includes basic stuff like adding items, tiles, objects, monsters, recipes and more. It also includes build tools using Gradle to easily compile and structure your mod so that it can be read and loaded by the game, as well as development tools like loading your in-development mod, so that you can upload it to the Steam Workshop when complete.&lt;br /&gt;
&lt;br /&gt;
=== Modding tools ===&lt;br /&gt;
* An integrated development environment (IDE). For example [https://www.jetbrains.com/idea/download Intellij IDEA Community] which is free.&lt;br /&gt;
* A Java development kit. The game is built using Adoptium Java17, which you can find [https://adoptium.net/temurin/releases/?version=17 here] but for compatibility reasons is still only using language level 8. If you are using the Intellij IDE, this is not needed as a JDK is already included in it. Make sure you are using language level 8 by going to File -&amp;gt; Project Structure... -&amp;gt; Language Level.&lt;br /&gt;
* An image editing tool, like pixel art editors [https://www.aseprite.org/ Aseprite] or [https://www.pyxeledit.com/ Pyxel Edit].&lt;br /&gt;
* An audio editing tool, like [https://www.audacityteam.org/ Audacity] or [https://www.reaper.fm/ REAPER].&lt;br /&gt;
&lt;br /&gt;
=== Setting up ===&lt;br /&gt;
If you have downloaded the example project, it can be loaded using your IDE and almost everything will already be set up for you. All you have to do is configure your &#039;&#039;build.gradle&#039;&#039; file with the correct mod info and the games install directory. Once done, it will prompt you to refresh the project.&lt;br /&gt;
&lt;br /&gt;
=== Running and testing your mod ===&lt;br /&gt;
[[File:Mod runClient Task.png|thumb|Image of where the gradle task can be found inside Intellij]]&lt;br /&gt;
To run your in-development mod, you will need to launch the game with &#039;&#039;-mod &amp;lt;folder path with your mod jar&amp;gt;&#039;&#039; option. This is already done for you if you are using the example project and run the &#039;&#039;runClient&#039;&#039; Gradle task. It can be found in the far-right toolbar inside Intellij (see image). Using this launch option will also allow you to upload your mod to Workshop once it is complete.&lt;br /&gt;
&lt;br /&gt;
==== Testing multiplayer ====&lt;br /&gt;
To test multiplayer, you can run one client with the &#039;&#039;runClient&#039;&#039; Gradle task, and another with the &#039;&#039;runDevClient&#039;&#039; Gradle task. One client should host the game, while the other should connect through the multiplayer menu. The hosted game should show up as a LAN server, or you can manually connect to it by using &amp;quot;localhost&amp;quot; as IP the address. The dev client will load into the game with a different authentication ID, allowing you to have 2 clients inside the same server.&lt;br /&gt;
&lt;br /&gt;
It&#039;s also important to test the dedicated server since it does not have access to the resources the clients load on startup. To do this, run the &#039;&#039;runServer&#039;&#039; Gradle task, and run your regular client at the same time. Same as above, you should then be able to see the game inside the multiplayer menu as a LAN server, or you can manually connect to it by using &amp;quot;localhost&amp;quot; as IP the address.&lt;br /&gt;
&lt;br /&gt;
=== Mod info file ===&lt;br /&gt;
Note: If you are using the example mod, you can skip this section as it is generated for you using the values you set inside the &#039;&#039;build.gradle&#039;&#039; file.&lt;br /&gt;
&lt;br /&gt;
Every mod must have a &#039;&#039;mod.info&#039;&#039; file in their jar&#039;s top path. The file structure is custom, but very similar to JSON. It&#039;s used throughout the game&#039;s saved files.&lt;br /&gt;
The file must have these fields:&lt;br /&gt;
* &#039;&#039;&#039;id&#039;&#039;&#039; - The unique ID of your mod. Must be all lowercase and cannot use special characters.&lt;br /&gt;
* &#039;&#039;&#039;name&#039;&#039;&#039; - The display name of your mod.&lt;br /&gt;
* &#039;&#039;&#039;version&#039;&#039;&#039; - The version of your mod.&lt;br /&gt;
* &#039;&#039;&#039;gameVersion&#039;&#039;&#039; - The target game version of your mod.&lt;br /&gt;
* &#039;&#039;&#039;description&#039;&#039;&#039; - A short description of your mod.&lt;br /&gt;
* &#039;&#039;&#039;author&#039;&#039;&#039; - Your name&lt;br /&gt;
* &#039;&#039;&#039;dependencies&#039;&#039;&#039; (optional) - Your mods dependencies are formatted in their IDs and array. Like this: [exammple.mod, other.mod]&lt;br /&gt;
* &#039;&#039;&#039;optionalDependecies&#039;&#039;&#039; (optional) - Your mods optional dependencies. They are used together with your dependencies to automatically make a load order for mods.&lt;br /&gt;
* &#039;&#039;&#039;clientside&#039;&#039;&#039; (optional) - true/false, if your mod is client/server-side only. This makes it possible for clients to connect to servers without the server needing the mod and vice versa. Defaults to false.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important notes about your mod.info file:&#039;&#039;&#039;&lt;br /&gt;
# Your id should be unique to the mod and never change between versions. A good example for id is &amp;quot;&amp;lt;your name&amp;gt;.&amp;lt;mod name&amp;gt;&amp;quot;.&lt;br /&gt;
# Avoid special characters that might inflict with the format, like commas, quotes, etc. This will probably be changed later, and you’ll be able to escape characters, just like in Java.&lt;br /&gt;
&lt;br /&gt;
Example of a mod.info file:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
   id = fair.examplemod,&lt;br /&gt;
   name = Example Mod,&lt;br /&gt;
   version = 1.0,&lt;br /&gt;
   gameVersion = 1.1.1,&lt;br /&gt;
   description = Just an example mod,&lt;br /&gt;
   author = Fair&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Mod entry class ===&lt;br /&gt;
Your mod needs an entry class. This is where the game loads your mod from and calls initialization methods. Create a class with the @ModEntry annotation to tell the game that&#039;s where your mod starts.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important notes about your @ModEntry class:&#039;&#039;&#039;&lt;br /&gt;
# Make sure your mod only has one @ModEntry annotation. The game will stop looking for more when found one.&lt;br /&gt;
# Make sure the class does NOT have a constructor.&lt;br /&gt;
&lt;br /&gt;
Example for your mod entry class:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=Java&amp;gt;&lt;br /&gt;
import necesse.engine.modLoader.annotations.ModEntry;&lt;br /&gt;
&lt;br /&gt;
@ModEntry&lt;br /&gt;
public class ExampleMod {&lt;br /&gt;
&lt;br /&gt;
    public void init() {&lt;br /&gt;
        System.out.println(&amp;quot;Hello world from my example mod!&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
The game will look for specific methods within your @ModEntry class. Here&#039;s a description of them:&lt;br /&gt;
&lt;br /&gt;
==== public void preInit() ====&lt;br /&gt;
This method is called before loading of the core game. It should only be used on rare occasions. If you are not sure about it, don&#039;t use it.&lt;br /&gt;
&lt;br /&gt;
==== public void init() ====&lt;br /&gt;
This method is called after the core game has been loaded. Here you should register your own tiles, objects, items, mobs and so on.&lt;br /&gt;
&lt;br /&gt;
The general order in which you should register your mod objects to avoid issues are (not forced):&lt;br /&gt;
# Tiles&lt;br /&gt;
# Objects&lt;br /&gt;
# Biomes&lt;br /&gt;
# Buffs&lt;br /&gt;
# Global ingredients&lt;br /&gt;
# Recipe techs&lt;br /&gt;
# Items&lt;br /&gt;
# Enchantments&lt;br /&gt;
# Mobs&lt;br /&gt;
# Pickup entities and projectiles&lt;br /&gt;
# Level, world events, level data and settlers&lt;br /&gt;
# Containers&lt;br /&gt;
# World generators&lt;br /&gt;
# Packets&lt;br /&gt;
# Quests&lt;br /&gt;
# Other&lt;br /&gt;
&lt;br /&gt;
==== public void initResources() ====&lt;br /&gt;
This method is called only on the client and should load any extra resources your mod uses that the game doesn&#039;t automatically load.&lt;br /&gt;
&lt;br /&gt;
The resources will be loaded from a resource folder. You can read more about this in a later section.&lt;br /&gt;
&lt;br /&gt;
Example: Assign a texture:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;GameTexture texture = GameTexture.fromFile(&amp;quot;path/to/file&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you have a texture at resources/texture.png you can load it using &amp;lt;code&amp;gt;GameTexture.fromFile(&amp;quot;texture&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
All sound (.ogg) files need to be placed in resources/sound folder and can be loaded using&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;GameSound.fromFile(&amp;quot;path/to/file&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For example, a song placed in resources/sound/music/MySong.ogg would be loaded as &amp;lt;code&amp;gt;GameSound.fromFile(&amp;quot;music/MySong&amp;quot;)&amp;lt;/code&amp;gt;, ommiting resources/sound&lt;br /&gt;
&lt;br /&gt;
For information on music paths to override music, look at &amp;lt;code&amp;gt;MusicRegistry.registerCore&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== public void postInit() ====&lt;br /&gt;
This method is called after the game is done loading all its core, mods and resources.&lt;br /&gt;
&lt;br /&gt;
This is where you should register recipes, create or modify loot tables and spawn tables and register chat commands.&lt;br /&gt;
&lt;br /&gt;
==== public void dispose() ====&lt;br /&gt;
This method is called when the game closes. If you have anything that needs to be disposed, that the game doesn&#039;t already dispose on it&#039;s own, do it here.&lt;br /&gt;
&lt;br /&gt;
Things like textured loaded using &amp;lt;code&amp;gt;GameTexture.fromFile(...)&amp;lt;/code&amp;gt; and sounds are automatically disposed.&lt;br /&gt;
&lt;br /&gt;
=== Building your mod ===&lt;br /&gt;
If you are using the example project, a lot of this is already done for you. Simply run the &#039;&#039;buildModJar&#039;&#039; Gradle task, and it will generate the jar inside the ./build/jar folder.&lt;br /&gt;
&lt;br /&gt;
For the game to recognize your jar, it has to follow a specific structure:&lt;br /&gt;
;ExampleMod.jar&lt;br /&gt;
: ↳ resources&lt;br /&gt;
:: ↳ Your resource files&lt;br /&gt;
: ↳ Java class files&lt;br /&gt;
: ↳ mod.info file&lt;br /&gt;
&lt;br /&gt;
=== Uploading your mod ===&lt;br /&gt;
[[File:Upload mod.png|thumb|Image of the upload button when mod is loaded from development]]&lt;br /&gt;
To upload your mod to the Steam workshop, a few conditions have to be met:&lt;br /&gt;
* Must be enabled&lt;br /&gt;
* Must have a preview.png file in the resources folder&lt;br /&gt;
* Must be loaded through the -mod launch option (this is done automatically in the example project when running the &#039;&#039;runClient&#039;&#039; Gradle task. You can find more info about this under the beginning of the setting up section).&lt;br /&gt;
When all of these conditions are met, a button to upload your mod will appear when you select it inside the main menu mods screen. Click this and it will walk you through uploading to workshop. When you first upload, the mod will be hidden and only you will be able to see it. You can change this when you are ready to launch on your mods workshop page.&lt;br /&gt;
&lt;br /&gt;
=== Localization ===&lt;br /&gt;
Localization files are needed to give your tiles, objects, items, mobs and other things names. The files should be placed inside the resources/locale folder, and be named the same as the language they are using. Example: en.lang for the english translation.&lt;br /&gt;
&lt;br /&gt;
You can also see how the localization file is structured inside the example mod project.&lt;br /&gt;
&lt;br /&gt;
==== The file structure ====&lt;br /&gt;
The file is divided up into categories and keys. If your item has the localization &#039;&#039;item.exampleitem&#039;&#039;, it means that it&#039;s under the &#039;&#039;item&#039;&#039; category and has the key &#039;&#039;exampleitem&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
The language file is read line by line in order. If one line is a category change, all the next keys will be under that category. Here&#039;s an example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
[mycategory]&lt;br /&gt;
mykey=Text&lt;br /&gt;
otherkey=Other text&lt;br /&gt;
&lt;br /&gt;
[newcategory]&lt;br /&gt;
differentkey=Different text&lt;br /&gt;
&lt;br /&gt;
[item]&lt;br /&gt;
exampleitem=Example item&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Translations can have replacements that can be done in runtime. To add a replacement key in your translation, add a &amp;lt;key&amp;gt; somewhere. The key can be anything like &amp;lt;name&amp;gt;, &amp;lt;number&amp;gt; etc. Example: &amp;lt;code&amp;gt;mobhealth=Mob health: &amp;lt;health&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Using a translation inside the game ====&lt;br /&gt;
&amp;lt;code&amp;gt;Localization.translate(category, key)&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;Localization.translate(category, key, replaceKey1, replaceString1, replaceKey2, replaceString2, ...)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A lot of places also use the GameMessage class. This is essentially a localizable string, by using LocalMessage which extends GameMessage. Goes the same as above:&lt;br /&gt;
&amp;lt;code&amp;gt;new LocalMessage(category, key, replaceKey1, replaceString1, replaceKey2, replaceString2, ...)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you don&#039;t want to use a translation, you can also just give it a static string with &amp;lt;code&amp;gt;new StaticMessage(string...)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Resources ===&lt;br /&gt;
For the game to load your resources, they have to be placed inside a resources folder in your mod jar.&lt;br /&gt;
&lt;br /&gt;
Using this, it is also possible to overwrite existing ingame textures by placing another texture at the exact same path as the core game ones. In the Discord server, there is a wiki channel with a pinned message where the core textures can be downloaded and used for modding and this wiki.&lt;br /&gt;
&lt;br /&gt;
This also means that your resource files can get overwritten by other mods, so try and keep your file names unique.&lt;br /&gt;
&lt;br /&gt;
Resource loading happens automatically for any files in the resources folder. But some things will look at specific subfolders to load their textures. Examples:&lt;br /&gt;
* &#039;&#039;&#039;Items&#039;&#039;&#039; - items/&amp;lt;item stringiD&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Buffs&#039;&#039;&#039; - buffs/&amp;lt;buff stringiD&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Biomes&#039;&#039;&#039; - biomes/&amp;lt;biome stringiD&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Projectiles&#039;&#039;&#039; - projectiles/&amp;lt;projectile stringiD&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== More documentation ==&lt;br /&gt;
Until more documentation gets migrated and added to this wiki, you can use the old documentation here: [https://docs.google.com/document/u/1/d/e/2PACX-1vTexy0ZwJmztm6KhvwUCpSbgdNFV5hxUOr_6rSiCyqvjlj80Sj28Alenodq6AbOfnKaWoj-zv0iziyL/pub Published Google docs file]&lt;br /&gt;
[[Modding Snippets]] Has examples of other modders coding work that can be used to help you out.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Accessing Necesse Java files ==&lt;br /&gt;
[[File:Decompile1.png|thumb|Decompile1]]&lt;br /&gt;
[[File:Decompile2.png|thumb|Decompile2]]&lt;br /&gt;
[[File:Decompile3.png|thumb|Decompile3]]&lt;br /&gt;
[[File:Decompile4.png|thumb|Decompile4]]&lt;br /&gt;
using the IDE mentioned in [[Modding#Modding_tools|Modding Tools]], you can decompile java files and take a peek at the core game values.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{stub|reason = Need to reformat this section}}&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Note: Java may need to be installed for this process&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
You probably need to have Java installed.(external links not allowed) &amp;lt;br&amp;gt;&lt;br /&gt;
Download and install the Windows x64 .msi file&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Rough Transcript from Discord User Snoobinoob, to be refined:&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Open up IntelliJ IDEA and create a new Java project wherever&amp;lt;br&amp;gt;&lt;br /&gt;
File &amp;gt; New &amp;gt; Project...&amp;lt;br&amp;gt;&lt;br /&gt;
Can leave all settings as is&amp;lt;br&amp;gt;&lt;br /&gt;
Once the project is created, open up the project structure&amp;lt;br&amp;gt;&lt;br /&gt;
File &amp;gt; Project Structure... (Ctrl+Alt+Shift+S)&amp;lt;br&amp;gt;&lt;br /&gt;
select &amp;quot;Modules&amp;quot; from the left navigaiton pane&amp;lt;br&amp;gt;&lt;br /&gt;
Click the dependencies tab on the top-right-ish (Decompile1)&amp;lt;br&amp;gt;&lt;br /&gt;
Click the + icon to add a new module and choose &amp;quot;JARs or Directories&amp;quot; (Decompile2)&amp;lt;br&amp;gt;&lt;br /&gt;
Browse to the steam files location of Necesse.jar&amp;lt;br&amp;gt;&lt;br /&gt;
Should be something like: C:\Program Files (x86)\Steam\steamapps\common\Necesse\Necesse.jar&amp;lt;br&amp;gt;&lt;br /&gt;
Should see this (or similar) after clicking the +, choosing JARs or Directories, and browsing to the Necesse.jar location (Decompile3)&amp;lt;br&amp;gt;&lt;br /&gt;
Click OK, and you should now see Necesse.jar in the list of dependencies in the previous Modules window&amp;lt;br&amp;gt;&lt;br /&gt;
Click OK again to close the project structure window&amp;lt;br&amp;gt;&lt;br /&gt;
Necesse.jar should now be visible in External Libraries (Decompile4)&amp;lt;br&amp;gt;&lt;br /&gt;
Everything should now be set up, so you can search via the Navigate &amp;gt; Search Everywhere menu option&amp;lt;br&amp;gt;&lt;br /&gt;
Exactly what to search is up to you, and not always the most obvious&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jamesp1989</name></author>
	</entry>
	<entry>
		<id>https://necessewiki.com/mediawiki/index.php?title=Modding&amp;diff=24726</id>
		<title>Modding</title>
		<link rel="alternate" type="text/html" href="https://necessewiki.com/mediawiki/index.php?title=Modding&amp;diff=24726"/>
		<updated>2026-02-04T02:42:55Z</updated>

		<summary type="html">&lt;p&gt;Jamesp1989: moved over to syntax highlighting&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Modding is the act of modifying, adding or removing content and features. Mods are created by the community, and shared through the [https://steamcommunity.com/app/1169040/workshop/ Steam Workshop]. They can be anything like adding more items and monsters, adding a new language, changing the textures in the game, adding new features, tweaking balance and much more.&lt;br /&gt;
&lt;br /&gt;
Necesse mods are created using the Java programming language.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Installing and using mods ==&lt;br /&gt;
=== Steam Workshop ===&lt;br /&gt;
Modders usually share their mods on the [https://steamcommunity.com/app/1169040/workshop/ Steam Workshop]. If you subscribe to a mod, the next time you launch the game a mods button will appear in the main menu. In this menu you can see the mods you have installed, change their load order, enable or disable them.&lt;br /&gt;
=== Dedicated servers and local mods ===&lt;br /&gt;
For dedicated servers to have mods, they must find and download the mod jar file. Many modders give links to where they can be downloaded on the mods Workshop page. Once you have the jar file, you have to put it inside a mods folder, depending on your system. &amp;lt;br&amp;gt;&lt;br /&gt;
If the folder does not exist on your system, you can create one yourself.&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Note: ONLY the jar file is needed for the mod to be active, the rest of the files within the example mod are for gradle tasks to help make testing easier&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Windows:&#039;&#039;&#039; %APPDATA%/Necesse/mods/   &lt;br /&gt;
* &#039;&#039;&#039;Linux:&#039;&#039;&#039; ~/.config/Necesse/mods&lt;br /&gt;
* &#039;&#039;&#039;Mac:&#039;&#039;&#039; ~/Library/Application Support/Necesse/mods/&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Windows dedicated Server over steamcmd &#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Install your server as usual with steamcmd with the AppID 1169370.&lt;br /&gt;
&lt;br /&gt;
Create then in your server install directory a new folder mods&lt;br /&gt;
as example: c:\Servers\Necesse\mods&lt;br /&gt;
&lt;br /&gt;
Then you have to edit the server start parameters (in startserver-nogui.bat)&lt;br /&gt;
&lt;br /&gt;
default:&lt;br /&gt;
start jre\bin\java.exe -jar Server.jar -nogui %*&lt;br /&gt;
&lt;br /&gt;
edit in:&lt;br /&gt;
start jre\bin\java.exe -jar Server.jar -nogui -datadir .\data -mod .\mods&lt;br /&gt;
&lt;br /&gt;
Then copy your .jar mod files downloaded over the steam workshop as explained earlier in this thread into the mods folder. The server will recognize on startup the mods in the folder and loads them.&lt;br /&gt;
&lt;br /&gt;
== Texture/Resource packs ==&lt;br /&gt;
Texture packs are not officially supported, except through the modding system. However, it is still possible to overwrite existing textures inside the game. To do so, follow the steps:&lt;br /&gt;
&lt;br /&gt;
# Download the official textures, found on the [https://discord.gg/FAFgrKD Official Discord server], in a pinned message inside the wiki channel.&lt;br /&gt;
# Browse to the games install directory. You can do so by right-clicking the game in your Steam library -&amp;gt; Manage -&amp;gt; Browse local files.&lt;br /&gt;
# Extract the texture files into &amp;quot;&amp;lt;Necesse install directory&amp;gt;/res&amp;quot;. If the &amp;quot;res&amp;quot; folder does not exist, you have to create it yourself.&lt;br /&gt;
&lt;br /&gt;
The next time you launch the game, the textures will be loaded from those extracted files. This means you can edit or replace any of the files and that will then be loaded instead.&lt;br /&gt;
&lt;br /&gt;
== Creating mods ==&lt;br /&gt;
Necesse mods are created using the Java programming language. This place is not for you to learn Java, there are plenty of tutorials and resources on that out on the internet already.&lt;br /&gt;
&lt;br /&gt;
Mods are packaged inside a jar file for the game to load during runtime. When modding, it&#039;s a good idea to have a decompiler (included in most IDEs). The source code won&#039;t be released yet (if ever), and many topics are not explained thoroughly yet. This means you often have to rely on decompiling classes and checking out how they are done in the core game.&lt;br /&gt;
&lt;br /&gt;
[https://discord.gg/FAFgrKD The Official Discord Server] has a channel dedicated to modding where you can ask questions, get help and request new modding features for the game and all other things Necesse modding.&lt;br /&gt;
&lt;br /&gt;
=== New in v. 0.21.27 ===&lt;br /&gt;
&#039;&#039;If you are just starting out modding, you can skip this section.&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
In version 0.21.27 and forward, the game has changed the Java runtime environment it used. If you try to launch the game with the old runtime environment, you may run into crashes or other problems. You can download the runtime currently being used [https://adoptium.net/temurin/releases/?version=17 here]. To help with compatibility, the language level is still version 8. In IntelliJ, you can change your JDK and language level by going to File -&amp;gt; Project Structure... -&amp;gt; Project. Make sure that Gradle is also using the correct JDK by going to File -&amp;gt; Settings -&amp;gt; Build, Execution and Deployment -&amp;gt; Build Tools -&amp;gt; Gradle -&amp;gt; Gradle JVM. The example project has been updated to use this new Java and Gradle version.&lt;br /&gt;
&lt;br /&gt;
=== Getting started and example project ===&lt;br /&gt;
To get started on modding, there is an &#039;&#039;&#039;[https://github.com/DrFair/ExampleMod official example project you can download, found on Github].&#039;&#039;&#039; It includes basic stuff like adding items, tiles, objects, monsters, recipes and more. It also includes build tools using Gradle to easily compile and structure your mod so that it can be read and loaded by the game, as well as development tools like loading your in-development mod, so that you can upload it to the Steam Workshop when complete.&lt;br /&gt;
&lt;br /&gt;
=== Modding tools ===&lt;br /&gt;
* An integrated development environment (IDE). For example [https://www.jetbrains.com/idea/download Intellij IDEA Community] which is free.&lt;br /&gt;
* A Java development kit. The game is built using Adoptium Java17, which you can find [https://adoptium.net/temurin/releases/?version=17 here] but for compatibility reasons is still only using language level 8. If you are using the Intellij IDE, this is not needed as a JDK is already included in it. Make sure you are using language level 8 by going to File -&amp;gt; Project Structure... -&amp;gt; Language Level.&lt;br /&gt;
* An image editing tool, like pixel art editors [https://www.aseprite.org/ Aseprite] or [https://www.pyxeledit.com/ Pyxel Edit].&lt;br /&gt;
* An audio editing tool, like [https://www.audacityteam.org/ Audacity] or [https://www.reaper.fm/ REAPER].&lt;br /&gt;
&lt;br /&gt;
=== Setting up ===&lt;br /&gt;
If you have downloaded the example project, it can be loaded using your IDE and almost everything will already be set up for you. All you have to do is configure your &#039;&#039;build.gradle&#039;&#039; file with the correct mod info and the games install directory. Once done, it will prompt you to refresh the project.&lt;br /&gt;
&lt;br /&gt;
=== Running and testing your mod ===&lt;br /&gt;
[[File:Mod runClient Task.png|thumb|Image of where the gradle task can be found inside Intellij]]&lt;br /&gt;
To run your in-development mod, you will need to launch the game with &#039;&#039;-mod &amp;lt;folder path with your mod jar&amp;gt;&#039;&#039; option. This is already done for you if you are using the example project and run the &#039;&#039;runClient&#039;&#039; Gradle task. It can be found in the far-right toolbar inside Intellij (see image). Using this launch option will also allow you to upload your mod to Workshop once it is complete.&lt;br /&gt;
&lt;br /&gt;
==== Testing multiplayer ====&lt;br /&gt;
To test multiplayer, you can run one client with the &#039;&#039;runClient&#039;&#039; Gradle task, and another with the &#039;&#039;runDevClient&#039;&#039; Gradle task. One client should host the game, while the other should connect through the multiplayer menu. The hosted game should show up as a LAN server, or you can manually connect to it by using &amp;quot;localhost&amp;quot; as IP the address. The dev client will load into the game with a different authentication ID, allowing you to have 2 clients inside the same server.&lt;br /&gt;
&lt;br /&gt;
It&#039;s also important to test the dedicated server since it does not have access to the resources the clients load on startup. To do this, run the &#039;&#039;runServer&#039;&#039; Gradle task, and run your regular client at the same time. Same as above, you should then be able to see the game inside the multiplayer menu as a LAN server, or you can manually connect to it by using &amp;quot;localhost&amp;quot; as IP the address.&lt;br /&gt;
&lt;br /&gt;
=== Mod info file ===&lt;br /&gt;
Note: If you are using the example mod, you can skip this section as it is generated for you using the values you set inside the &#039;&#039;build.gradle&#039;&#039; file.&lt;br /&gt;
&lt;br /&gt;
Every mod must have a &#039;&#039;mod.info&#039;&#039; file in their jar&#039;s top path. The file structure is custom, but very similar to JSON. It&#039;s used throughout the game&#039;s saved files.&lt;br /&gt;
The file must have these fields:&lt;br /&gt;
* &#039;&#039;&#039;id&#039;&#039;&#039; - The unique ID of your mod. Must be all lowercase and cannot use special characters.&lt;br /&gt;
* &#039;&#039;&#039;name&#039;&#039;&#039; - The display name of your mod.&lt;br /&gt;
* &#039;&#039;&#039;version&#039;&#039;&#039; - The version of your mod.&lt;br /&gt;
* &#039;&#039;&#039;gameVersion&#039;&#039;&#039; - The target game version of your mod.&lt;br /&gt;
* &#039;&#039;&#039;description&#039;&#039;&#039; - A short description of your mod.&lt;br /&gt;
* &#039;&#039;&#039;author&#039;&#039;&#039; - Your name&lt;br /&gt;
* &#039;&#039;&#039;dependencies&#039;&#039;&#039; (optional) - Your mods dependencies are formatted in their IDs and array. Like this: [exammple.mod, other.mod]&lt;br /&gt;
* &#039;&#039;&#039;optionalDependecies&#039;&#039;&#039; (optional) - Your mods optional dependencies. They are used together with your dependencies to automatically make a load order for mods.&lt;br /&gt;
* &#039;&#039;&#039;clientside&#039;&#039;&#039; (optional) - true/false, if your mod is client/server-side only. This makes it possible for clients to connect to servers without the server needing the mod and vice versa. Defaults to false.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important notes about your mod.info file:&#039;&#039;&#039;&lt;br /&gt;
# Your id should be unique to the mod and never change between versions. A good example for id is &amp;quot;&amp;lt;your name&amp;gt;.&amp;lt;mod name&amp;gt;&amp;quot;.&lt;br /&gt;
# Avoid special characters that might inflict with the format, like commas, quotes, etc. This will probably be changed later, and you’ll be able to escape characters, just like in Java.&lt;br /&gt;
&lt;br /&gt;
Example of a mod.info file:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
   id = fair.examplemod,&lt;br /&gt;
   name = Example Mod,&lt;br /&gt;
   version = 1.0,&lt;br /&gt;
   gameVersion = 1.1.1,&lt;br /&gt;
   description = Just an example mod,&lt;br /&gt;
   author = Fair&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Mod entry class ===&lt;br /&gt;
Your mod needs an entry class. This is where the game loads your mod from and calls initialization methods. Create a class with the @ModEntry annotation to tell the game that&#039;s where your mod starts.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important notes about your @ModEntry class:&#039;&#039;&#039;&lt;br /&gt;
# Make sure your mod only has one @ModEntry annotation. The game will stop looking for more when found one.&lt;br /&gt;
# Make sure the class does NOT have a constructor.&lt;br /&gt;
&lt;br /&gt;
Example for your mod entry class:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=Java&amp;gt;&lt;br /&gt;
import necesse.engine.modLoader.annotations.ModEntry;&lt;br /&gt;
&lt;br /&gt;
@ModEntry&lt;br /&gt;
public class ExampleMod {&lt;br /&gt;
&lt;br /&gt;
    public void init() {&lt;br /&gt;
        System.out.println(&amp;quot;Hello world from my example mod!&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
The game will look for specific methods within your @ModEntry class. Here&#039;s a description of them:&lt;br /&gt;
&lt;br /&gt;
==== public void preInit() ====&lt;br /&gt;
This method is called before loading of the core game. It should only be used on rare occasions. If you are not sure about it, don&#039;t use it.&lt;br /&gt;
&lt;br /&gt;
==== public void init() ====&lt;br /&gt;
This method is called after the core game has been loaded. Here you should register your own tiles, objects, items, mobs and so on.&lt;br /&gt;
&lt;br /&gt;
The general order in which you should register your mod objects to avoid issues are (not forced):&lt;br /&gt;
# Tiles&lt;br /&gt;
# Objects&lt;br /&gt;
# Biomes&lt;br /&gt;
# Buffs&lt;br /&gt;
# Global ingredients&lt;br /&gt;
# Recipe techs&lt;br /&gt;
# Items&lt;br /&gt;
# Enchantments&lt;br /&gt;
# Mobs&lt;br /&gt;
# Pickup entities and projectiles&lt;br /&gt;
# Level, world events, level data and settlers&lt;br /&gt;
# Containers&lt;br /&gt;
# World generators&lt;br /&gt;
# Packets&lt;br /&gt;
# Quests&lt;br /&gt;
# Other&lt;br /&gt;
&lt;br /&gt;
==== public void initResources() ====&lt;br /&gt;
This method is called only on the client and should load any extra resources your mod uses that the game doesn&#039;t automatically load.&lt;br /&gt;
&lt;br /&gt;
The resources will be loaded from a resource folder. You can read more about this in a later section.&lt;br /&gt;
&lt;br /&gt;
Example: Assign a texture:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;GameTexture texture = GameTexture.fromFile(&amp;quot;path/to/file&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you have a texture at resources/texture.png you can load it using &amp;lt;code&amp;gt;GameTexture.fromFile(&amp;quot;texture&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
All sound (.ogg) files need to be placed in resources/sound folder and can be loaded using&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;GameSound.fromFile(&amp;quot;path/to/file&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For example, a song placed in resources/sound/music/MySong.ogg would be loaded as &amp;lt;code&amp;gt;GameSound.fromFile(&amp;quot;music/MySong&amp;quot;)&amp;lt;/code&amp;gt;, ommiting resources/sound&lt;br /&gt;
&lt;br /&gt;
For information on music paths to override music, look at &amp;lt;code&amp;gt;MusicRegistry.registerCore&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== public void postInit() ====&lt;br /&gt;
This method is called after the game is done loading all its core, mods and resources.&lt;br /&gt;
&lt;br /&gt;
This is where you should register recipes, create or modify loot tables and spawn tables and register chat commands.&lt;br /&gt;
&lt;br /&gt;
==== public void dispose() ====&lt;br /&gt;
This method is called when the game closes. If you have anything that needs to be disposed, that the game doesn&#039;t already dispose on it&#039;s own, do it here.&lt;br /&gt;
&lt;br /&gt;
Things like textured loaded using &amp;lt;code&amp;gt;GameTexture.fromFile(...)&amp;lt;/code&amp;gt; and sounds are automatically disposed.&lt;br /&gt;
&lt;br /&gt;
=== Building your mod ===&lt;br /&gt;
If you are using the example project, a lot of this is already done for you. Simply run the &#039;&#039;buildModJar&#039;&#039; Gradle task, and it will generate the jar inside the ./build/jar folder.&lt;br /&gt;
&lt;br /&gt;
For the game to recognize your jar, it has to follow a specific structure:&lt;br /&gt;
;ExampleMod.jar&lt;br /&gt;
: ↳ resources&lt;br /&gt;
:: ↳ Your resource files&lt;br /&gt;
: ↳ Java class files&lt;br /&gt;
: ↳ mod.info file&lt;br /&gt;
&lt;br /&gt;
=== Uploading your mod ===&lt;br /&gt;
[[File:Upload mod.png|thumb|Image of the upload button when mod is loaded from development]]&lt;br /&gt;
To upload your mod to the Steam workshop, a few conditions have to be met:&lt;br /&gt;
* Must be enabled&lt;br /&gt;
* Must have a preview.png file in the resources folder&lt;br /&gt;
* Must be loaded through the -mod launch option (this is done automatically in the example project when running the &#039;&#039;runClient&#039;&#039; Gradle task. You can find more info about this under the beginning of the setting up section).&lt;br /&gt;
When all of these conditions are met, a button to upload your mod will appear when you select it inside the main menu mods screen. Click this and it will walk you through uploading to workshop. When you first upload, the mod will be hidden and only you will be able to see it. You can change this when you are ready to launch on your mods workshop page.&lt;br /&gt;
&lt;br /&gt;
=== Localization ===&lt;br /&gt;
Localization files are needed to give your tiles, objects, items, mobs and other things names. The files should be placed inside the resources/locale folder, and be named the same as the language they are using. Example: en.lang for the english translation.&lt;br /&gt;
&lt;br /&gt;
You can also see how the localization file is structured inside the example mod project.&lt;br /&gt;
&lt;br /&gt;
==== The file structure ====&lt;br /&gt;
The file is divided up into categories and keys. If your item has the localization &#039;&#039;item.exampleitem&#039;&#039;, it means that it&#039;s under the &#039;&#039;item&#039;&#039; category and has the key &#039;&#039;exampleitem&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
The language file is read line by line in order. If one line is a category change, all the next keys will be under that category. Here&#039;s an example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
[mycategory]&lt;br /&gt;
mykey=Text&lt;br /&gt;
otherkey=Other text&lt;br /&gt;
&lt;br /&gt;
[newcategory]&lt;br /&gt;
differentkey=Different text&lt;br /&gt;
&lt;br /&gt;
[item]&lt;br /&gt;
exampleitem=Example item&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Translations can have replacements that can be done in runtime. To add a replacement key in your translation, add a &amp;lt;key&amp;gt; somewhere. The key can be anything like &amp;lt;name&amp;gt;, &amp;lt;number&amp;gt; etc. Example: &amp;lt;code&amp;gt;mobhealth=Mob health: &amp;lt;health&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Using a translation inside the game ====&lt;br /&gt;
&amp;lt;code&amp;gt;Localization.translate(category, key)&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;Localization.translate(category, key, replaceKey1, replaceString1, replaceKey2, replaceString2, ...)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A lot of places also use the GameMessage class. This is essentially a localizable string, by using LocalMessage which extends GameMessage. Goes the same as above:&lt;br /&gt;
&amp;lt;code&amp;gt;new LocalMessage(category, key, replaceKey1, replaceString1, replaceKey2, replaceString2, ...)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you don&#039;t want to use a translation, you can also just give it a static string with &amp;lt;code&amp;gt;new StaticMessage(string...)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Resources ===&lt;br /&gt;
For the game to load your resources, they have to be placed inside a resources folder in your mod jar.&lt;br /&gt;
&lt;br /&gt;
Using this, it is also possible to overwrite existing ingame textures by placing another texture at the exact same path as the core game ones. In the Discord server, there is a wiki channel with a pinned message where the core textures can be downloaded and used for modding and this wiki.&lt;br /&gt;
&lt;br /&gt;
This also means that your resource files can get overwritten by other mods, so try and keep your file names unique.&lt;br /&gt;
&lt;br /&gt;
Resource loading happens automatically for any files in the resources folder. But some things will look at specific subfolders to load their textures. Examples:&lt;br /&gt;
* &#039;&#039;&#039;Items&#039;&#039;&#039; - items/&amp;lt;item stringiD&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Buffs&#039;&#039;&#039; - buffs/&amp;lt;buff stringiD&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Biomes&#039;&#039;&#039; - biomes/&amp;lt;biome stringiD&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Projectiles&#039;&#039;&#039; - projectiles/&amp;lt;projectile stringiD&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== More documentation ==&lt;br /&gt;
Until more documentation gets migrated and added to this wiki, you can use the old documentation here: [https://docs.google.com/document/u/1/d/e/2PACX-1vTexy0ZwJmztm6KhvwUCpSbgdNFV5hxUOr_6rSiCyqvjlj80Sj28Alenodq6AbOfnKaWoj-zv0iziyL/pub Published Google docs file]&lt;br /&gt;
[[Modding Snippets]] Has examples of other modders coding work that can be used to help you out.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Accessing Necesse Java files ==&lt;br /&gt;
[[File:Decompile1.png|thumb|Decompile1]]&lt;br /&gt;
[[File:Decompile2.png|thumb|Decompile2]]&lt;br /&gt;
[[File:Decompile3.png|thumb|Decompile3]]&lt;br /&gt;
[[File:Decompile4.png|thumb|Decompile4]]&lt;br /&gt;
using the IDE mentioned in [[Modding#Modding_tools|Modding Tools]], you can decompile java files and take a peek at the core game values.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{stub|reason = Need to reformat this section}}&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Note: Java may need to be installed for this process&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
You probably need to have Java installed.(external links not allowed) &amp;lt;br&amp;gt;&lt;br /&gt;
Download and install the Windows x64 .msi file&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Rough Transcript from Discord User Snoobinoob, to be refined:&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Open up IntelliJ IDEA and create a new Java project wherever&amp;lt;br&amp;gt;&lt;br /&gt;
File &amp;gt; New &amp;gt; Project...&amp;lt;br&amp;gt;&lt;br /&gt;
Can leave all settings as is&amp;lt;br&amp;gt;&lt;br /&gt;
Once the project is created, open up the project structure&amp;lt;br&amp;gt;&lt;br /&gt;
File &amp;gt; Project Structure... (Ctrl+Alt+Shift+S)&amp;lt;br&amp;gt;&lt;br /&gt;
select &amp;quot;Modules&amp;quot; from the left navigaiton pane&amp;lt;br&amp;gt;&lt;br /&gt;
Click the dependencies tab on the top-right-ish (Decompile1)&amp;lt;br&amp;gt;&lt;br /&gt;
Click the + icon to add a new module and choose &amp;quot;JARs or Directories&amp;quot; (Decompile2)&amp;lt;br&amp;gt;&lt;br /&gt;
Browse to the steam files location of Necesse.jar&amp;lt;br&amp;gt;&lt;br /&gt;
Should be something like: C:\Program Files (x86)\Steam\steamapps\common\Necesse\Necesse.jar&amp;lt;br&amp;gt;&lt;br /&gt;
Should see this (or similar) after clicking the +, choosing JARs or Directories, and browsing to the Necesse.jar location (Decompile3)&amp;lt;br&amp;gt;&lt;br /&gt;
Click OK, and you should now see Necesse.jar in the list of dependencies in the previous Modules window&amp;lt;br&amp;gt;&lt;br /&gt;
Click OK again to close the project structure window&amp;lt;br&amp;gt;&lt;br /&gt;
Necesse.jar should now be visible in External Libraries (Decompile4)&amp;lt;br&amp;gt;&lt;br /&gt;
Everything should now be set up, so you can search via the Navigate &amp;gt; Search Everywhere menu option&amp;lt;br&amp;gt;&lt;br /&gt;
Exactly what to search is up to you, and not always the most obvious&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jamesp1989</name></author>
	</entry>
	<entry>
		<id>https://necessewiki.com/mediawiki/index.php?title=Modding&amp;diff=24725</id>
		<title>Modding</title>
		<link rel="alternate" type="text/html" href="https://necessewiki.com/mediawiki/index.php?title=Modding&amp;diff=24725"/>
		<updated>2026-02-04T02:35:59Z</updated>

		<summary type="html">&lt;p&gt;Jamesp1989: Moved the code block to actually use our shiny (now working syntax highlighter thanks @fair)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Modding is the act of modifying, adding or removing content and features. Mods are created by the community, and shared through the [https://steamcommunity.com/app/1169040/workshop/ Steam Workshop]. They can be anything like adding more items and monsters, adding a new language, changing the textures in the game, adding new features, tweaking balance and much more.&lt;br /&gt;
&lt;br /&gt;
Necesse mods are created using the Java programming language.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Installing and using mods ==&lt;br /&gt;
=== Steam Workshop ===&lt;br /&gt;
Modders usually share their mods on the [https://steamcommunity.com/app/1169040/workshop/ Steam Workshop]. If you subscribe to a mod, the next time you launch the game a mods button will appear in the main menu. In this menu you can see the mods you have installed, change their load order, enable or disable them.&lt;br /&gt;
=== Dedicated servers and local mods ===&lt;br /&gt;
For dedicated servers to have mods, they must find and download the mod jar file. Many modders give links to where they can be downloaded on the mods Workshop page. Once you have the jar file, you have to put it inside a mods folder, depending on your system. &amp;lt;br&amp;gt;&lt;br /&gt;
If the folder does not exist on your system, you can create one yourself.&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Note: ONLY the jar file is needed for the mod to be active, the rest of the files within the example mod are for gradle tasks to help make testing easier&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Windows:&#039;&#039;&#039; %APPDATA%/Necesse/mods/   &lt;br /&gt;
* &#039;&#039;&#039;Linux:&#039;&#039;&#039; ~/.config/Necesse/mods&lt;br /&gt;
* &#039;&#039;&#039;Mac:&#039;&#039;&#039; ~/Library/Application Support/Necesse/mods/&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Windows dedicated Server over steamcmd &#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Install your server as usual with steamcmd with the AppID 1169370.&lt;br /&gt;
&lt;br /&gt;
Create then in your server install directory a new folder mods&lt;br /&gt;
as example: c:\Servers\Necesse\mods&lt;br /&gt;
&lt;br /&gt;
Then you have to edit the server start parameters (in startserver-nogui.bat)&lt;br /&gt;
&lt;br /&gt;
default:&lt;br /&gt;
start jre\bin\java.exe -jar Server.jar -nogui %*&lt;br /&gt;
&lt;br /&gt;
edit in:&lt;br /&gt;
start jre\bin\java.exe -jar Server.jar -nogui -datadir .\data -mod .\mods&lt;br /&gt;
&lt;br /&gt;
Then copy your .jar mod files downloaded over the steam workshop as explained earlier in this thread into the mods folder. The server will recognize on startup the mods in the folder and loads them.&lt;br /&gt;
&lt;br /&gt;
== Texture/Resource packs ==&lt;br /&gt;
Texture packs are not officially supported, except through the modding system. However, it is still possible to overwrite existing textures inside the game. To do so, follow the steps:&lt;br /&gt;
&lt;br /&gt;
# Download the official textures, found on the [https://discord.gg/FAFgrKD Official Discord server], in a pinned message inside the wiki channel.&lt;br /&gt;
# Browse to the games install directory. You can do so by right-clicking the game in your Steam library -&amp;gt; Manage -&amp;gt; Browse local files.&lt;br /&gt;
# Extract the texture files into &amp;quot;&amp;lt;Necesse install directory&amp;gt;/res&amp;quot;. If the &amp;quot;res&amp;quot; folder does not exist, you have to create it yourself.&lt;br /&gt;
&lt;br /&gt;
The next time you launch the game, the textures will be loaded from those extracted files. This means you can edit or replace any of the files and that will then be loaded instead.&lt;br /&gt;
&lt;br /&gt;
== Creating mods ==&lt;br /&gt;
Necesse mods are created using the Java programming language. This place is not for you to learn Java, there are plenty of tutorials and resources on that out on the internet already.&lt;br /&gt;
&lt;br /&gt;
Mods are packaged inside a jar file for the game to load during runtime. When modding, it&#039;s a good idea to have a decompiler (included in most IDEs). The source code won&#039;t be released yet (if ever), and many topics are not explained thoroughly yet. This means you often have to rely on decompiling classes and checking out how they are done in the core game.&lt;br /&gt;
&lt;br /&gt;
[https://discord.gg/FAFgrKD The Official Discord Server] has a channel dedicated to modding where you can ask questions, get help and request new modding features for the game and all other things Necesse modding.&lt;br /&gt;
&lt;br /&gt;
=== New in v. 0.21.27 ===&lt;br /&gt;
&#039;&#039;If you are just starting out modding, you can skip this section.&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
In version 0.21.27 and forward, the game has changed the Java runtime environment it used. If you try to launch the game with the old runtime environment, you may run into crashes or other problems. You can download the runtime currently being used [https://adoptium.net/temurin/releases/?version=17 here]. To help with compatibility, the language level is still version 8. In IntelliJ, you can change your JDK and language level by going to File -&amp;gt; Project Structure... -&amp;gt; Project. Make sure that Gradle is also using the correct JDK by going to File -&amp;gt; Settings -&amp;gt; Build, Execution and Deployment -&amp;gt; Build Tools -&amp;gt; Gradle -&amp;gt; Gradle JVM. The example project has been updated to use this new Java and Gradle version.&lt;br /&gt;
&lt;br /&gt;
=== Getting started and example project ===&lt;br /&gt;
To get started on modding, there is an &#039;&#039;&#039;[https://github.com/DrFair/ExampleMod official example project you can download, found on Github].&#039;&#039;&#039; It includes basic stuff like adding items, tiles, objects, monsters, recipes and more. It also includes build tools using Gradle to easily compile and structure your mod so that it can be read and loaded by the game, as well as development tools like loading your in-development mod, so that you can upload it to the Steam Workshop when complete.&lt;br /&gt;
&lt;br /&gt;
=== Modding tools ===&lt;br /&gt;
* An integrated development environment (IDE). For example [https://www.jetbrains.com/idea/download Intellij IDEA Community] which is free.&lt;br /&gt;
* A Java development kit. The game is built using Adoptium Java17, which you can find [https://adoptium.net/temurin/releases/?version=17 here] but for compatibility reasons is still only using language level 8. If you are using the Intellij IDE, this is not needed as a JDK is already included in it. Make sure you are using language level 8 by going to File -&amp;gt; Project Structure... -&amp;gt; Language Level.&lt;br /&gt;
* An image editing tool, like pixel art editors [https://www.aseprite.org/ Aseprite] or [https://www.pyxeledit.com/ Pyxel Edit].&lt;br /&gt;
* An audio editing tool, like [https://www.audacityteam.org/ Audacity] or [https://www.reaper.fm/ REAPER].&lt;br /&gt;
&lt;br /&gt;
=== Setting up ===&lt;br /&gt;
If you have downloaded the example project, it can be loaded using your IDE and almost everything will already be set up for you. All you have to do is configure your &#039;&#039;build.gradle&#039;&#039; file with the correct mod info and the games install directory. Once done, it will prompt you to refresh the project.&lt;br /&gt;
&lt;br /&gt;
=== Running and testing your mod ===&lt;br /&gt;
[[File:Mod runClient Task.png|thumb|Image of where the gradle task can be found inside Intellij]]&lt;br /&gt;
To run your in-development mod, you will need to launch the game with &#039;&#039;-mod &amp;lt;folder path with your mod jar&amp;gt;&#039;&#039; option. This is already done for you if you are using the example project and run the &#039;&#039;runClient&#039;&#039; Gradle task. It can be found in the far-right toolbar inside Intellij (see image). Using this launch option will also allow you to upload your mod to Workshop once it is complete.&lt;br /&gt;
&lt;br /&gt;
==== Testing multiplayer ====&lt;br /&gt;
To test multiplayer, you can run one client with the &#039;&#039;runClient&#039;&#039; Gradle task, and another with the &#039;&#039;runDevClient&#039;&#039; Gradle task. One client should host the game, while the other should connect through the multiplayer menu. The hosted game should show up as a LAN server, or you can manually connect to it by using &amp;quot;localhost&amp;quot; as IP the address. The dev client will load into the game with a different authentication ID, allowing you to have 2 clients inside the same server.&lt;br /&gt;
&lt;br /&gt;
It&#039;s also important to test the dedicated server since it does not have access to the resources the clients load on startup. To do this, run the &#039;&#039;runServer&#039;&#039; Gradle task, and run your regular client at the same time. Same as above, you should then be able to see the game inside the multiplayer menu as a LAN server, or you can manually connect to it by using &amp;quot;localhost&amp;quot; as IP the address.&lt;br /&gt;
&lt;br /&gt;
=== Mod info file ===&lt;br /&gt;
Note: If you are using the example mod, you can skip this section as it is generated for you using the values you set inside the &#039;&#039;build.gradle&#039;&#039; file.&lt;br /&gt;
&lt;br /&gt;
Every mod must have a &#039;&#039;mod.info&#039;&#039; file in their jar&#039;s top path. The file structure is custom, but very similar to JSON. It&#039;s used throughout the game&#039;s saved files.&lt;br /&gt;
The file must have these fields:&lt;br /&gt;
* &#039;&#039;&#039;id&#039;&#039;&#039; - The unique ID of your mod. Must be all lowercase and cannot use special characters.&lt;br /&gt;
* &#039;&#039;&#039;name&#039;&#039;&#039; - The display name of your mod.&lt;br /&gt;
* &#039;&#039;&#039;version&#039;&#039;&#039; - The version of your mod.&lt;br /&gt;
* &#039;&#039;&#039;gameVersion&#039;&#039;&#039; - The target game version of your mod.&lt;br /&gt;
* &#039;&#039;&#039;description&#039;&#039;&#039; - A short description of your mod.&lt;br /&gt;
* &#039;&#039;&#039;author&#039;&#039;&#039; - Your name&lt;br /&gt;
* &#039;&#039;&#039;dependencies&#039;&#039;&#039; (optional) - Your mods dependencies are formatted in their IDs and array. Like this: [exammple.mod, other.mod]&lt;br /&gt;
* &#039;&#039;&#039;optionalDependecies&#039;&#039;&#039; (optional) - Your mods optional dependencies. They are used together with your dependencies to automatically make a load order for mods.&lt;br /&gt;
* &#039;&#039;&#039;clientside&#039;&#039;&#039; (optional) - true/false, if your mod is client/server-side only. This makes it possible for clients to connect to servers without the server needing the mod and vice versa. Defaults to false.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important notes about your mod.info file:&#039;&#039;&#039;&lt;br /&gt;
# Your id should be unique to the mod and never change between versions. A good example for id is &amp;quot;&amp;lt;your name&amp;gt;.&amp;lt;mod name&amp;gt;&amp;quot;.&lt;br /&gt;
# Avoid special characters that might inflict with the format, like commas, quotes, etc. This will probably be changed later, and you’ll be able to escape characters, just like in Java.&lt;br /&gt;
&lt;br /&gt;
Example of a mod.info file:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
   id = fair.examplemod,&lt;br /&gt;
   name = Example Mod,&lt;br /&gt;
   version = 1.0,&lt;br /&gt;
   gameVersion = 1.1.1,&lt;br /&gt;
   description = Just an example mod,&lt;br /&gt;
   author = Fair&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Mod entry class ===&lt;br /&gt;
Your mod needs an entry class. This is where the game loads your mod from and calls initialization methods. Create a class with the @ModEntry annotation to tell the game that&#039;s where your mod starts.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important notes about your @ModEntry class:&#039;&#039;&#039;&lt;br /&gt;
# Make sure your mod only has one @ModEntry annotation. The game will stop looking for more when found one.&lt;br /&gt;
# Make sure the class does NOT have a constructor.&lt;br /&gt;
&lt;br /&gt;
Example for your mod entry class:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=Java&amp;gt;&lt;br /&gt;
import necesse.engine.modLoader.annotations.ModEntry;&lt;br /&gt;
&lt;br /&gt;
@ModEntry&lt;br /&gt;
public class ExampleMod {&lt;br /&gt;
&lt;br /&gt;
    public void init() {&lt;br /&gt;
        System.out.println(&amp;quot;Hello world from my example mod!&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
The game will look for specific methods within your @ModEntry class. Here&#039;s a description of them:&lt;br /&gt;
&lt;br /&gt;
==== public void preInit() ====&lt;br /&gt;
This method is called before loading of the core game. It should only be used on rare occasions. If you are not sure about it, don&#039;t use it.&lt;br /&gt;
&lt;br /&gt;
==== public void init() ====&lt;br /&gt;
This method is called after the core game has been loaded. Here you should register your own tiles, objects, items, mobs and so on.&lt;br /&gt;
&lt;br /&gt;
The general order in which you should register your mod objects to avoid issues are (not forced):&lt;br /&gt;
# Tiles&lt;br /&gt;
# Objects&lt;br /&gt;
# Biomes&lt;br /&gt;
# Buffs&lt;br /&gt;
# Global ingredients&lt;br /&gt;
# Recipe techs&lt;br /&gt;
# Items&lt;br /&gt;
# Enchantments&lt;br /&gt;
# Mobs&lt;br /&gt;
# Pickup entities and projectiles&lt;br /&gt;
# Level, world events, level data and settlers&lt;br /&gt;
# Containers&lt;br /&gt;
# World generators&lt;br /&gt;
# Packets&lt;br /&gt;
# Quests&lt;br /&gt;
# Other&lt;br /&gt;
&lt;br /&gt;
==== public void initResources() ====&lt;br /&gt;
This method is called only on the client and should load any extra resources your mod uses that the game doesn&#039;t automatically load.&lt;br /&gt;
&lt;br /&gt;
The resources will be loaded from a resource folder. You can read more about this in a later section.&lt;br /&gt;
&lt;br /&gt;
Example: Assign a texture:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;GameTexture texture = GameTexture.fromFile(&amp;quot;path/to/file&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you have a texture at resources/texture.png you can load it using &amp;lt;code&amp;gt;GameTexture.fromFile(&amp;quot;texture&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
All sound (.ogg) files need to be placed in resources/sound folder and can be loaded using&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;GameSound.fromFile(&amp;quot;path/to/file&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For example, a song placed in resources/sound/music/MySong.ogg would be loaded as &amp;lt;code&amp;gt;GameSound.fromFile(&amp;quot;music/MySong&amp;quot;)&amp;lt;/code&amp;gt;, ommiting resources/sound&lt;br /&gt;
&lt;br /&gt;
For information on music paths to override music, look at &amp;lt;code&amp;gt;MusicRegistry.registerCore&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== public void postInit() ====&lt;br /&gt;
This method is called after the game is done loading all its core, mods and resources.&lt;br /&gt;
&lt;br /&gt;
This is where you should register recipes, create or modify loot tables and spawn tables and register chat commands.&lt;br /&gt;
&lt;br /&gt;
==== public void dispose() ====&lt;br /&gt;
This method is called when the game closes. If you have anything that needs to be disposed, that the game doesn&#039;t already dispose on it&#039;s own, do it here.&lt;br /&gt;
&lt;br /&gt;
Things like textured loaded using &amp;lt;code&amp;gt;GameTexture.fromFile(...)&amp;lt;/code&amp;gt; and sounds are automatically disposed.&lt;br /&gt;
&lt;br /&gt;
=== Building your mod ===&lt;br /&gt;
If you are using the example project, a lot of this is already done for you. Simply run the &#039;&#039;buildModJar&#039;&#039; Gradle task, and it will generate the jar inside the ./build/jar folder.&lt;br /&gt;
&lt;br /&gt;
For the game to recognize your jar, it has to follow a specific structure:&lt;br /&gt;
;ExampleMod.jar&lt;br /&gt;
: ↳ resources&lt;br /&gt;
:: ↳ Your resource files&lt;br /&gt;
: ↳ Java class files&lt;br /&gt;
: ↳ mod.info file&lt;br /&gt;
&lt;br /&gt;
=== Uploading your mod ===&lt;br /&gt;
[[File:Upload mod.png|thumb|Image of the upload button when mod is loaded from development]]&lt;br /&gt;
To upload your mod to the Steam workshop, a few conditions have to be met:&lt;br /&gt;
* Must be enabled&lt;br /&gt;
* Must have a preview.png file in the resources folder&lt;br /&gt;
* Must be loaded through the -mod launch option (this is done automatically in the example project when running the &#039;&#039;runClient&#039;&#039; Gradle task. You can find more info about this under the beginning of the setting up section).&lt;br /&gt;
When all of these conditions are met, a button to upload your mod will appear when you select it inside the main menu mods screen. Click this and it will walk you through uploading to workshop. When you first upload, the mod will be hidden and only you will be able to see it. You can change this when you are ready to launch on your mods workshop page.&lt;br /&gt;
&lt;br /&gt;
=== Localization ===&lt;br /&gt;
Localization files are needed to give your tiles, objects, items, mobs and other things names. The files should be placed inside the resources/locale folder, and be named the same as the language they are using. Example: en.lang for the english translation.&lt;br /&gt;
&lt;br /&gt;
You can also see how the localization file is structured inside the example mod project.&lt;br /&gt;
&lt;br /&gt;
==== The file structure ====&lt;br /&gt;
The file is divided up into categories and keys. If your item has the localization &#039;&#039;item.exampleitem&#039;&#039;, it means that it&#039;s under the &#039;&#039;item&#039;&#039; category and has the key &#039;&#039;exampleitem&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
The language file is read line by line in order. If one line is a category change, all the next keys will be under that category. Here&#039;s an example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[mycategory]&lt;br /&gt;
mykey=Text&lt;br /&gt;
otherkey=Other text&lt;br /&gt;
&lt;br /&gt;
[newcategory]&lt;br /&gt;
differentkey=Different text&lt;br /&gt;
&lt;br /&gt;
[item]&lt;br /&gt;
exampleitem=Example item&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Translations can have replacements that can be done in runtime. To add a replacement key in your translation, add a &amp;lt;key&amp;gt; somewhere. The key can be anything like &amp;lt;name&amp;gt;, &amp;lt;number&amp;gt; etc. Example: &amp;lt;code&amp;gt;mobhealth=Mob health: &amp;lt;health&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Using a translation inside the game ====&lt;br /&gt;
&amp;lt;code&amp;gt;Localization.translate(category, key)&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;Localization.translate(category, key, replaceKey1, replaceString1, replaceKey2, replaceString2, ...)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A lot of places also use the GameMessage class. This is essentially a localizable string, by using LocalMessage which extends GameMessage. Goes the same as above:&lt;br /&gt;
&amp;lt;code&amp;gt;new LocalMessage(category, key, replaceKey1, replaceString1, replaceKey2, replaceString2, ...)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you don&#039;t want to use a translation, you can also just give it a static string with &amp;lt;code&amp;gt;new StaticMessage(string...)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Resources ===&lt;br /&gt;
For the game to load your resources, they have to be placed inside a resources folder in your mod jar.&lt;br /&gt;
&lt;br /&gt;
Using this, it is also possible to overwrite existing ingame textures by placing another texture at the exact same path as the core game ones. In the Discord server, there is a wiki channel with a pinned message where the core textures can be downloaded and used for modding and this wiki.&lt;br /&gt;
&lt;br /&gt;
This also means that your resource files can get overwritten by other mods, so try and keep your file names unique.&lt;br /&gt;
&lt;br /&gt;
Resource loading happens automatically for any files in the resources folder. But some things will look at specific subfolders to load their textures. Examples:&lt;br /&gt;
* &#039;&#039;&#039;Items&#039;&#039;&#039; - items/&amp;lt;item stringiD&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Buffs&#039;&#039;&#039; - buffs/&amp;lt;buff stringiD&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Biomes&#039;&#039;&#039; - biomes/&amp;lt;biome stringiD&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Projectiles&#039;&#039;&#039; - projectiles/&amp;lt;projectile stringiD&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== More documentation ==&lt;br /&gt;
Until more documentation gets migrated and added to this wiki, you can use the old documentation here: [https://docs.google.com/document/u/1/d/e/2PACX-1vTexy0ZwJmztm6KhvwUCpSbgdNFV5hxUOr_6rSiCyqvjlj80Sj28Alenodq6AbOfnKaWoj-zv0iziyL/pub Published Google docs file]&lt;br /&gt;
[[Modding Snippets]] Has examples of other modders coding work that can be used to help you out.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Accessing Necesse Java files ==&lt;br /&gt;
[[File:Decompile1.png|thumb|Decompile1]]&lt;br /&gt;
[[File:Decompile2.png|thumb|Decompile2]]&lt;br /&gt;
[[File:Decompile3.png|thumb|Decompile3]]&lt;br /&gt;
[[File:Decompile4.png|thumb|Decompile4]]&lt;br /&gt;
using the IDE mentioned in [[Modding#Modding_tools|Modding Tools]], you can decompile java files and take a peek at the core game values.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{stub|reason = Need to reformat this section}}&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Note: Java may need to be installed for this process&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
You probably need to have Java installed.(external links not allowed) &amp;lt;br&amp;gt;&lt;br /&gt;
Download and install the Windows x64 .msi file&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Rough Transcript from Discord User Snoobinoob, to be refined:&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Open up IntelliJ IDEA and create a new Java project wherever&amp;lt;br&amp;gt;&lt;br /&gt;
File &amp;gt; New &amp;gt; Project...&amp;lt;br&amp;gt;&lt;br /&gt;
Can leave all settings as is&amp;lt;br&amp;gt;&lt;br /&gt;
Once the project is created, open up the project structure&amp;lt;br&amp;gt;&lt;br /&gt;
File &amp;gt; Project Structure... (Ctrl+Alt+Shift+S)&amp;lt;br&amp;gt;&lt;br /&gt;
select &amp;quot;Modules&amp;quot; from the left navigaiton pane&amp;lt;br&amp;gt;&lt;br /&gt;
Click the dependencies tab on the top-right-ish (Decompile1)&amp;lt;br&amp;gt;&lt;br /&gt;
Click the + icon to add a new module and choose &amp;quot;JARs or Directories&amp;quot; (Decompile2)&amp;lt;br&amp;gt;&lt;br /&gt;
Browse to the steam files location of Necesse.jar&amp;lt;br&amp;gt;&lt;br /&gt;
Should be something like: C:\Program Files (x86)\Steam\steamapps\common\Necesse\Necesse.jar&amp;lt;br&amp;gt;&lt;br /&gt;
Should see this (or similar) after clicking the +, choosing JARs or Directories, and browsing to the Necesse.jar location (Decompile3)&amp;lt;br&amp;gt;&lt;br /&gt;
Click OK, and you should now see Necesse.jar in the list of dependencies in the previous Modules window&amp;lt;br&amp;gt;&lt;br /&gt;
Click OK again to close the project structure window&amp;lt;br&amp;gt;&lt;br /&gt;
Necesse.jar should now be visible in External Libraries (Decompile4)&amp;lt;br&amp;gt;&lt;br /&gt;
Everything should now be set up, so you can search via the Navigate &amp;gt; Search Everywhere menu option&amp;lt;br&amp;gt;&lt;br /&gt;
Exactly what to search is up to you, and not always the most obvious&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jamesp1989</name></author>
	</entry>
	<entry>
		<id>https://necessewiki.com/mediawiki/index.php?title=Cactus&amp;diff=24688</id>
		<title>Cactus</title>
		<link rel="alternate" type="text/html" href="https://necessewiki.com/mediawiki/index.php?title=Cactus&amp;diff=24688"/>
		<updated>2026-01-20T22:26:50Z</updated>

		<summary type="html">&lt;p&gt;Jamesp1989: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Infobox item&lt;br /&gt;
|stringID       = {{FULLPAGENAME}}&lt;br /&gt;
|name           = {{FULLPAGENAME}}&lt;br /&gt;
|image          = {{FULLPAGENAME}}.png&lt;br /&gt;
|type           = [[Saplings]]&lt;br /&gt;
|type2           = [[Other Plants]]&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
[[{{FULLPAGENAME}}]] is a sapling that can be obtained by cutting [[Other Plants|cactuses]] in [[Desert Biome]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[{{FULLPAGENAME}}]] can be planted on [[Sand|Sand Tiles]] and [[Farmland]] and is harvested via Forestry.&lt;br /&gt;
&lt;br /&gt;
[[{{FULLPAGENAME}}]] grows in 30-45 minutes.&lt;br /&gt;
&lt;br /&gt;
{{CraftingSection}}&lt;br /&gt;
[[Category:Objects]][[Category:Saplings]][[Category:Plants]][[Category:Other Plants]]&lt;/div&gt;</summary>
		<author><name>Jamesp1989</name></author>
	</entry>
	<entry>
		<id>https://necessewiki.com/mediawiki/index.php?title=Modding/draft&amp;diff=24684</id>
		<title>Modding/draft</title>
		<link rel="alternate" type="text/html" href="https://necessewiki.com/mediawiki/index.php?title=Modding/draft&amp;diff=24684"/>
		<updated>2026-01-16T07:51:54Z</updated>

		<summary type="html">&lt;p&gt;Jamesp1989: /* Next steps */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{ItemList&lt;br /&gt;
|compact&lt;br /&gt;
|&lt;br /&gt;
What this guide covers&lt;br /&gt;
|This is a beginner-focused guide to making a Necesse mod, based on what the game’s mod loader requires for a mod to be considered valid. It focuses on getting a mod to load successfully&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
= Beginner Guide: Making a Necesse Mod =&lt;br /&gt;
== What the game considers a “valid” mod ==&lt;br /&gt;
To be loaded by the game, your mod must meet these requirements:&lt;br /&gt;
{{ItemList|compact|&lt;br /&gt;
|&lt;br /&gt;
# &#039;&#039;&#039;It must be a &amp;lt;code&amp;gt;.jar&amp;lt;/code&amp;gt; file.&#039;&#039;&#039;&lt;br /&gt;
# &#039;&#039;&#039;The jar must contain a &amp;lt;code&amp;gt;mod.info&amp;lt;/code&amp;gt; file at the root of the jar.&#039;&#039;&#039;&lt;br /&gt;
# &#039;&#039;&#039;The &amp;lt;code&amp;gt;mod.info&amp;lt;/code&amp;gt; must include required fields&#039;&#039;&#039; (see below).&lt;br /&gt;
# &#039;&#039;&#039;The jar must contain exactly one mod entry class&#039;&#039;&#039; annotated with &amp;lt;code&amp;gt;@ModEntry&amp;lt;/code&amp;gt;.&lt;br /&gt;
# &#039;&#039;&#039;The mod entry class must have a public no-argument constructor.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
If any of these are missing, the loader will reject the mod or log an error.&lt;br /&gt;
}}&lt;br /&gt;
== Step 1: Pick a unique Java package ==&lt;br /&gt;
{{ItemList|compact|&lt;br /&gt;
|Before writing any code, choose a unique Java package name for your mod.&lt;br /&gt;
&lt;br /&gt;
Avoid using:&lt;br /&gt;
* &amp;lt;code&amp;gt;examplemod&amp;lt;/code&amp;gt; (the loader warns about this)&lt;br /&gt;
* &amp;lt;code&amp;gt;necesse&amp;lt;/code&amp;gt; (reserved for the base game)&lt;br /&gt;
* the default package (no package)&lt;br /&gt;
&lt;br /&gt;
Use something unique, for example:&lt;br /&gt;
* &amp;lt;code&amp;gt;com.yourname.yourmod&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;If your mod contains classes in the &amp;lt;code&amp;gt;examplemod&amp;lt;/code&amp;gt; package, the loader will log a warning. In dev mod loading it specifically warns that you must move packages to upload, and in normal loading it warns that this will likely not be allowed in future versions.&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
== Step 2: Create the mod.info file ==&lt;br /&gt;
{{ItemList|compact|&lt;br /&gt;
|&lt;br /&gt;
Create a plain text file named &amp;lt;code&amp;gt;mod.info&amp;lt;/code&amp;gt;. This file must be included in the jar at the &#039;&#039;&#039;root&#039;&#039;&#039; (top level).&lt;br /&gt;
&lt;br /&gt;
=== Required fields ===&lt;br /&gt;
The loader requires these fields to exist and not be empty:&lt;br /&gt;
* &amp;lt;code&amp;gt;id&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;version&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;gameVersion&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;author&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;description&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Optional fields ===&lt;br /&gt;
These are supported by the loader and are commonly included:&lt;br /&gt;
* &amp;lt;code&amp;gt;clientside&amp;lt;/code&amp;gt; (boolean)&lt;br /&gt;
* &amp;lt;code&amp;gt;dependencies&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;optionalDependencies&amp;lt;/code&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
=== Example mod.info ===&lt;br /&gt;
 id = &amp;quot;mytestmod&amp;quot;&lt;br /&gt;
 name = &amp;quot;My Test Mod&amp;quot;&lt;br /&gt;
 version = &amp;quot;1.0&amp;quot;&lt;br /&gt;
 gameVersion = &amp;quot;1.1.1&amp;quot;&lt;br /&gt;
 author = &amp;quot;YourName&amp;quot;&lt;br /&gt;
 description = &amp;quot;A beginner test mod.&amp;quot;&lt;br /&gt;
 clientside = false&lt;br /&gt;
 dependencies = []&lt;br /&gt;
 optionalDependencies = []&lt;br /&gt;
&lt;br /&gt;
{{ItemList|compact|&lt;br /&gt;
|The loader validates the format of &amp;lt;code&amp;gt;id&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;version&amp;lt;/code&amp;gt;. If you use strange characters or invalid version formatting, the mod can be rejected. Keep them simple (letters/numbers, dots, dashes).&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Step 3: Create your Mod Entry class ==&lt;br /&gt;
{{ItemList|compact|&lt;br /&gt;
|&lt;br /&gt;
A mod must have &#039;&#039;&#039;exactly one&#039;&#039;&#039; “entry point” class marked with the &amp;lt;code&amp;gt;@ModEntry&amp;lt;/code&amp;gt; annotation.&lt;br /&gt;
&lt;br /&gt;
Rules:&lt;br /&gt;
&lt;br /&gt;
If the loader finds &#039;&#039;&#039;no&#039;&#039;&#039; &amp;lt;code&amp;gt;@ModEntry&amp;lt;/code&amp;gt; class, the mod will not load.&lt;br /&gt;
&lt;br /&gt;
If the loader finds &#039;&#039;&#039;more than one&#039;&#039;&#039; &amp;lt;code&amp;gt;@ModEntry&amp;lt;/code&amp;gt; class, it errors.&lt;br /&gt;
&lt;br /&gt;
The class must have a &#039;&#039;&#039;public no-argument constructor&#039;&#039;&#039; because the loader creates it at runtime&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Minimal example ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=Java&amp;gt;&lt;br /&gt;
import necesse.engine.modLoader.annotations.ModEntry;&lt;br /&gt;
&lt;br /&gt;
@ModEntry&lt;br /&gt;
public class MyTestMod {&lt;br /&gt;
    public MyTestMod() {&lt;br /&gt;
        // Public no-arg constructor required by the loader&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Step 4: Build the jar with the correct contents ==&lt;br /&gt;
&lt;br /&gt;
When you build your mod, the final &amp;lt;code&amp;gt;.jar&amp;lt;/code&amp;gt; must contain:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/mod.info&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Your compiled class files, including the entry class&lt;br /&gt;
&lt;br /&gt;
A simple “jar contents” checklist:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/mod.info&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;/com/yourname/mytestmod/MyTestMod.class&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Optional: Mod lifecycle methods ==&lt;br /&gt;
The loader can call lifecycle methods on your mod entry class &#039;&#039;&#039;if they exist&#039;&#039;&#039;. If they do not exist, the loader simply skips them.&lt;br /&gt;
&lt;br /&gt;
Common lifecycle method names include:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;preInit()&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;init()&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;initResources()&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;postInit()&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;initSettings()&amp;lt;/code&amp;gt; (special case: if present, it must return a &amp;lt;code&amp;gt;ModSettings&amp;lt;/code&amp;gt; type)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dispose()&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
=== “Did not contain a mod.info file” ===&lt;br /&gt;
&lt;br /&gt;
Your jar is missing &amp;lt;code&amp;gt;mod.info&amp;lt;/code&amp;gt;, or it is not at the root of the jar.&lt;br /&gt;
&lt;br /&gt;
=== Mod is ignored / not loaded ===&lt;br /&gt;
&lt;br /&gt;
The file is not a &amp;lt;code&amp;gt;.jar&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The jar does not contain a valid &amp;lt;code&amp;gt;mod.info&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
No &amp;lt;code&amp;gt;@ModEntry&amp;lt;/code&amp;gt; class was found.&lt;br /&gt;
&lt;br /&gt;
=== Error about @ModEntry being used multiple times ===&lt;br /&gt;
&lt;br /&gt;
More than one class in your jar has &amp;lt;code&amp;gt;@ModEntry&amp;lt;/code&amp;gt;. You must have exactly one.&lt;br /&gt;
&lt;br /&gt;
=== Entry class fails to construct ===&lt;br /&gt;
&lt;br /&gt;
Your entry class does not have a public no-argument constructor.&lt;br /&gt;
&lt;br /&gt;
=== Warning about examplemod package ===&lt;br /&gt;
&lt;br /&gt;
Some of your classes are in &amp;lt;code&amp;gt;examplemod.*&amp;lt;/code&amp;gt;. Move them to a unique package.&lt;br /&gt;
&lt;br /&gt;
== Next steps ==&lt;br /&gt;
Once your mod loads successfully, you can start adding actual content and logic. A good first milestone is:&lt;br /&gt;
&lt;br /&gt;
Confirm the game loads your jar with no errors.&lt;br /&gt;
&lt;br /&gt;
Add one small change at a time (so you know what broke if something stops loading).&lt;/div&gt;</summary>
		<author><name>Jamesp1989</name></author>
	</entry>
	<entry>
		<id>https://necessewiki.com/mediawiki/index.php?title=Modding/draft&amp;diff=24683</id>
		<title>Modding/draft</title>
		<link rel="alternate" type="text/html" href="https://necessewiki.com/mediawiki/index.php?title=Modding/draft&amp;diff=24683"/>
		<updated>2026-01-16T07:51:25Z</updated>

		<summary type="html">&lt;p&gt;Jamesp1989: /* Step 4: Build the jar with the correct contents */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{ItemList&lt;br /&gt;
|compact&lt;br /&gt;
|&lt;br /&gt;
What this guide covers&lt;br /&gt;
|This is a beginner-focused guide to making a Necesse mod, based on what the game’s mod loader requires for a mod to be considered valid. It focuses on getting a mod to load successfully&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
= Beginner Guide: Making a Necesse Mod =&lt;br /&gt;
== What the game considers a “valid” mod ==&lt;br /&gt;
To be loaded by the game, your mod must meet these requirements:&lt;br /&gt;
{{ItemList|compact|&lt;br /&gt;
|&lt;br /&gt;
# &#039;&#039;&#039;It must be a &amp;lt;code&amp;gt;.jar&amp;lt;/code&amp;gt; file.&#039;&#039;&#039;&lt;br /&gt;
# &#039;&#039;&#039;The jar must contain a &amp;lt;code&amp;gt;mod.info&amp;lt;/code&amp;gt; file at the root of the jar.&#039;&#039;&#039;&lt;br /&gt;
# &#039;&#039;&#039;The &amp;lt;code&amp;gt;mod.info&amp;lt;/code&amp;gt; must include required fields&#039;&#039;&#039; (see below).&lt;br /&gt;
# &#039;&#039;&#039;The jar must contain exactly one mod entry class&#039;&#039;&#039; annotated with &amp;lt;code&amp;gt;@ModEntry&amp;lt;/code&amp;gt;.&lt;br /&gt;
# &#039;&#039;&#039;The mod entry class must have a public no-argument constructor.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
If any of these are missing, the loader will reject the mod or log an error.&lt;br /&gt;
}}&lt;br /&gt;
== Step 1: Pick a unique Java package ==&lt;br /&gt;
{{ItemList|compact|&lt;br /&gt;
|Before writing any code, choose a unique Java package name for your mod.&lt;br /&gt;
&lt;br /&gt;
Avoid using:&lt;br /&gt;
* &amp;lt;code&amp;gt;examplemod&amp;lt;/code&amp;gt; (the loader warns about this)&lt;br /&gt;
* &amp;lt;code&amp;gt;necesse&amp;lt;/code&amp;gt; (reserved for the base game)&lt;br /&gt;
* the default package (no package)&lt;br /&gt;
&lt;br /&gt;
Use something unique, for example:&lt;br /&gt;
* &amp;lt;code&amp;gt;com.yourname.yourmod&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;If your mod contains classes in the &amp;lt;code&amp;gt;examplemod&amp;lt;/code&amp;gt; package, the loader will log a warning. In dev mod loading it specifically warns that you must move packages to upload, and in normal loading it warns that this will likely not be allowed in future versions.&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
== Step 2: Create the mod.info file ==&lt;br /&gt;
{{ItemList|compact|&lt;br /&gt;
|&lt;br /&gt;
Create a plain text file named &amp;lt;code&amp;gt;mod.info&amp;lt;/code&amp;gt;. This file must be included in the jar at the &#039;&#039;&#039;root&#039;&#039;&#039; (top level).&lt;br /&gt;
&lt;br /&gt;
=== Required fields ===&lt;br /&gt;
The loader requires these fields to exist and not be empty:&lt;br /&gt;
* &amp;lt;code&amp;gt;id&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;version&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;gameVersion&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;author&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;description&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Optional fields ===&lt;br /&gt;
These are supported by the loader and are commonly included:&lt;br /&gt;
* &amp;lt;code&amp;gt;clientside&amp;lt;/code&amp;gt; (boolean)&lt;br /&gt;
* &amp;lt;code&amp;gt;dependencies&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;optionalDependencies&amp;lt;/code&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
=== Example mod.info ===&lt;br /&gt;
 id = &amp;quot;mytestmod&amp;quot;&lt;br /&gt;
 name = &amp;quot;My Test Mod&amp;quot;&lt;br /&gt;
 version = &amp;quot;1.0&amp;quot;&lt;br /&gt;
 gameVersion = &amp;quot;1.1.1&amp;quot;&lt;br /&gt;
 author = &amp;quot;YourName&amp;quot;&lt;br /&gt;
 description = &amp;quot;A beginner test mod.&amp;quot;&lt;br /&gt;
 clientside = false&lt;br /&gt;
 dependencies = []&lt;br /&gt;
 optionalDependencies = []&lt;br /&gt;
&lt;br /&gt;
{{ItemList|compact|&lt;br /&gt;
|The loader validates the format of &amp;lt;code&amp;gt;id&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;version&amp;lt;/code&amp;gt;. If you use strange characters or invalid version formatting, the mod can be rejected. Keep them simple (letters/numbers, dots, dashes).&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Step 3: Create your Mod Entry class ==&lt;br /&gt;
{{ItemList|compact|&lt;br /&gt;
|&lt;br /&gt;
A mod must have &#039;&#039;&#039;exactly one&#039;&#039;&#039; “entry point” class marked with the &amp;lt;code&amp;gt;@ModEntry&amp;lt;/code&amp;gt; annotation.&lt;br /&gt;
&lt;br /&gt;
Rules:&lt;br /&gt;
&lt;br /&gt;
If the loader finds &#039;&#039;&#039;no&#039;&#039;&#039; &amp;lt;code&amp;gt;@ModEntry&amp;lt;/code&amp;gt; class, the mod will not load.&lt;br /&gt;
&lt;br /&gt;
If the loader finds &#039;&#039;&#039;more than one&#039;&#039;&#039; &amp;lt;code&amp;gt;@ModEntry&amp;lt;/code&amp;gt; class, it errors.&lt;br /&gt;
&lt;br /&gt;
The class must have a &#039;&#039;&#039;public no-argument constructor&#039;&#039;&#039; because the loader creates it at runtime&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Minimal example ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=Java&amp;gt;&lt;br /&gt;
import necesse.engine.modLoader.annotations.ModEntry;&lt;br /&gt;
&lt;br /&gt;
@ModEntry&lt;br /&gt;
public class MyTestMod {&lt;br /&gt;
    public MyTestMod() {&lt;br /&gt;
        // Public no-arg constructor required by the loader&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Step 4: Build the jar with the correct contents ==&lt;br /&gt;
&lt;br /&gt;
When you build your mod, the final &amp;lt;code&amp;gt;.jar&amp;lt;/code&amp;gt; must contain:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/mod.info&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Your compiled class files, including the entry class&lt;br /&gt;
&lt;br /&gt;
A simple “jar contents” checklist:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/mod.info&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;/com/yourname/mytestmod/MyTestMod.class&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Optional: Mod lifecycle methods ==&lt;br /&gt;
The loader can call lifecycle methods on your mod entry class &#039;&#039;&#039;if they exist&#039;&#039;&#039;. If they do not exist, the loader simply skips them.&lt;br /&gt;
&lt;br /&gt;
Common lifecycle method names include:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;preInit()&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;init()&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;initResources()&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;postInit()&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;initSettings()&amp;lt;/code&amp;gt; (special case: if present, it must return a &amp;lt;code&amp;gt;ModSettings&amp;lt;/code&amp;gt; type)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dispose()&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
=== “Did not contain a mod.info file” ===&lt;br /&gt;
&lt;br /&gt;
Your jar is missing &amp;lt;code&amp;gt;mod.info&amp;lt;/code&amp;gt;, or it is not at the root of the jar.&lt;br /&gt;
&lt;br /&gt;
=== Mod is ignored / not loaded ===&lt;br /&gt;
&lt;br /&gt;
The file is not a &amp;lt;code&amp;gt;.jar&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The jar does not contain a valid &amp;lt;code&amp;gt;mod.info&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
No &amp;lt;code&amp;gt;@ModEntry&amp;lt;/code&amp;gt; class was found.&lt;br /&gt;
&lt;br /&gt;
=== Error about @ModEntry being used multiple times ===&lt;br /&gt;
&lt;br /&gt;
More than one class in your jar has &amp;lt;code&amp;gt;@ModEntry&amp;lt;/code&amp;gt;. You must have exactly one.&lt;br /&gt;
&lt;br /&gt;
=== Entry class fails to construct ===&lt;br /&gt;
&lt;br /&gt;
Your entry class does not have a public no-argument constructor.&lt;br /&gt;
&lt;br /&gt;
=== Warning about examplemod package ===&lt;br /&gt;
&lt;br /&gt;
Some of your classes are in &amp;lt;code&amp;gt;examplemod.*&amp;lt;/code&amp;gt;. Move them to a unique package.&lt;br /&gt;
&lt;br /&gt;
== Next steps ==&lt;br /&gt;
Once your mod loads successfully, you can start adding actual content and logic. A good first milestone is:&lt;br /&gt;
&lt;br /&gt;
Confirm the game loads your jar with no errors.&lt;br /&gt;
&lt;br /&gt;
Add one small change at a time (so you know what broke if something stops loading).&lt;br /&gt;
&lt;br /&gt;
{{Tip&lt;br /&gt;
|title=Keep it simple while learning&lt;br /&gt;
|text=The easiest way to learn modding is to keep each step small: get the mod to load, then add one feature, test, repeat.&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Jamesp1989</name></author>
	</entry>
	<entry>
		<id>https://necessewiki.com/mediawiki/index.php?title=Modding/draft&amp;diff=24682</id>
		<title>Modding/draft</title>
		<link rel="alternate" type="text/html" href="https://necessewiki.com/mediawiki/index.php?title=Modding/draft&amp;diff=24682"/>
		<updated>2026-01-16T07:50:07Z</updated>

		<summary type="html">&lt;p&gt;Jamesp1989: /* Optional: Mod lifecycle methods */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{ItemList&lt;br /&gt;
|compact&lt;br /&gt;
|&lt;br /&gt;
What this guide covers&lt;br /&gt;
|This is a beginner-focused guide to making a Necesse mod, based on what the game’s mod loader requires for a mod to be considered valid. It focuses on getting a mod to load successfully&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
= Beginner Guide: Making a Necesse Mod =&lt;br /&gt;
== What the game considers a “valid” mod ==&lt;br /&gt;
To be loaded by the game, your mod must meet these requirements:&lt;br /&gt;
{{ItemList|compact|&lt;br /&gt;
|&lt;br /&gt;
# &#039;&#039;&#039;It must be a &amp;lt;code&amp;gt;.jar&amp;lt;/code&amp;gt; file.&#039;&#039;&#039;&lt;br /&gt;
# &#039;&#039;&#039;The jar must contain a &amp;lt;code&amp;gt;mod.info&amp;lt;/code&amp;gt; file at the root of the jar.&#039;&#039;&#039;&lt;br /&gt;
# &#039;&#039;&#039;The &amp;lt;code&amp;gt;mod.info&amp;lt;/code&amp;gt; must include required fields&#039;&#039;&#039; (see below).&lt;br /&gt;
# &#039;&#039;&#039;The jar must contain exactly one mod entry class&#039;&#039;&#039; annotated with &amp;lt;code&amp;gt;@ModEntry&amp;lt;/code&amp;gt;.&lt;br /&gt;
# &#039;&#039;&#039;The mod entry class must have a public no-argument constructor.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
If any of these are missing, the loader will reject the mod or log an error.&lt;br /&gt;
}}&lt;br /&gt;
== Step 1: Pick a unique Java package ==&lt;br /&gt;
{{ItemList|compact|&lt;br /&gt;
|Before writing any code, choose a unique Java package name for your mod.&lt;br /&gt;
&lt;br /&gt;
Avoid using:&lt;br /&gt;
* &amp;lt;code&amp;gt;examplemod&amp;lt;/code&amp;gt; (the loader warns about this)&lt;br /&gt;
* &amp;lt;code&amp;gt;necesse&amp;lt;/code&amp;gt; (reserved for the base game)&lt;br /&gt;
* the default package (no package)&lt;br /&gt;
&lt;br /&gt;
Use something unique, for example:&lt;br /&gt;
* &amp;lt;code&amp;gt;com.yourname.yourmod&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;If your mod contains classes in the &amp;lt;code&amp;gt;examplemod&amp;lt;/code&amp;gt; package, the loader will log a warning. In dev mod loading it specifically warns that you must move packages to upload, and in normal loading it warns that this will likely not be allowed in future versions.&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
== Step 2: Create the mod.info file ==&lt;br /&gt;
{{ItemList|compact|&lt;br /&gt;
|&lt;br /&gt;
Create a plain text file named &amp;lt;code&amp;gt;mod.info&amp;lt;/code&amp;gt;. This file must be included in the jar at the &#039;&#039;&#039;root&#039;&#039;&#039; (top level).&lt;br /&gt;
&lt;br /&gt;
=== Required fields ===&lt;br /&gt;
The loader requires these fields to exist and not be empty:&lt;br /&gt;
* &amp;lt;code&amp;gt;id&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;version&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;gameVersion&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;author&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;description&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Optional fields ===&lt;br /&gt;
These are supported by the loader and are commonly included:&lt;br /&gt;
* &amp;lt;code&amp;gt;clientside&amp;lt;/code&amp;gt; (boolean)&lt;br /&gt;
* &amp;lt;code&amp;gt;dependencies&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;optionalDependencies&amp;lt;/code&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
=== Example mod.info ===&lt;br /&gt;
 id = &amp;quot;mytestmod&amp;quot;&lt;br /&gt;
 name = &amp;quot;My Test Mod&amp;quot;&lt;br /&gt;
 version = &amp;quot;1.0&amp;quot;&lt;br /&gt;
 gameVersion = &amp;quot;1.1.1&amp;quot;&lt;br /&gt;
 author = &amp;quot;YourName&amp;quot;&lt;br /&gt;
 description = &amp;quot;A beginner test mod.&amp;quot;&lt;br /&gt;
 clientside = false&lt;br /&gt;
 dependencies = []&lt;br /&gt;
 optionalDependencies = []&lt;br /&gt;
&lt;br /&gt;
{{ItemList|compact|&lt;br /&gt;
|The loader validates the format of &amp;lt;code&amp;gt;id&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;version&amp;lt;/code&amp;gt;. If you use strange characters or invalid version formatting, the mod can be rejected. Keep them simple (letters/numbers, dots, dashes).&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Step 3: Create your Mod Entry class ==&lt;br /&gt;
{{ItemList|compact|&lt;br /&gt;
|&lt;br /&gt;
A mod must have &#039;&#039;&#039;exactly one&#039;&#039;&#039; “entry point” class marked with the &amp;lt;code&amp;gt;@ModEntry&amp;lt;/code&amp;gt; annotation.&lt;br /&gt;
&lt;br /&gt;
Rules:&lt;br /&gt;
&lt;br /&gt;
If the loader finds &#039;&#039;&#039;no&#039;&#039;&#039; &amp;lt;code&amp;gt;@ModEntry&amp;lt;/code&amp;gt; class, the mod will not load.&lt;br /&gt;
&lt;br /&gt;
If the loader finds &#039;&#039;&#039;more than one&#039;&#039;&#039; &amp;lt;code&amp;gt;@ModEntry&amp;lt;/code&amp;gt; class, it errors.&lt;br /&gt;
&lt;br /&gt;
The class must have a &#039;&#039;&#039;public no-argument constructor&#039;&#039;&#039; because the loader creates it at runtime&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Minimal example ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=Java&amp;gt;&lt;br /&gt;
import necesse.engine.modLoader.annotations.ModEntry;&lt;br /&gt;
&lt;br /&gt;
@ModEntry&lt;br /&gt;
public class MyTestMod {&lt;br /&gt;
    public MyTestMod() {&lt;br /&gt;
        // Public no-arg constructor required by the loader&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Step 4: Build the jar with the correct contents ==&lt;br /&gt;
When you build your mod, the final &amp;lt;code&amp;gt;.jar&amp;lt;/code&amp;gt; must contain:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/mod.info&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Your compiled class files, including the entry class&lt;br /&gt;
&lt;br /&gt;
A simple “jar contents” checklist:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/mod.info&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;/com/yourname/mytestmod/MyTestMod.class&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Optional: Mod lifecycle methods ==&lt;br /&gt;
The loader can call lifecycle methods on your mod entry class &#039;&#039;&#039;if they exist&#039;&#039;&#039;. If they do not exist, the loader simply skips them.&lt;br /&gt;
&lt;br /&gt;
Common lifecycle method names include:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;preInit()&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;init()&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;initResources()&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;postInit()&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;initSettings()&amp;lt;/code&amp;gt; (special case: if present, it must return a &amp;lt;code&amp;gt;ModSettings&amp;lt;/code&amp;gt; type)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dispose()&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
=== “Did not contain a mod.info file” ===&lt;br /&gt;
&lt;br /&gt;
Your jar is missing &amp;lt;code&amp;gt;mod.info&amp;lt;/code&amp;gt;, or it is not at the root of the jar.&lt;br /&gt;
&lt;br /&gt;
=== Mod is ignored / not loaded ===&lt;br /&gt;
&lt;br /&gt;
The file is not a &amp;lt;code&amp;gt;.jar&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The jar does not contain a valid &amp;lt;code&amp;gt;mod.info&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
No &amp;lt;code&amp;gt;@ModEntry&amp;lt;/code&amp;gt; class was found.&lt;br /&gt;
&lt;br /&gt;
=== Error about @ModEntry being used multiple times ===&lt;br /&gt;
&lt;br /&gt;
More than one class in your jar has &amp;lt;code&amp;gt;@ModEntry&amp;lt;/code&amp;gt;. You must have exactly one.&lt;br /&gt;
&lt;br /&gt;
=== Entry class fails to construct ===&lt;br /&gt;
&lt;br /&gt;
Your entry class does not have a public no-argument constructor.&lt;br /&gt;
&lt;br /&gt;
=== Warning about examplemod package ===&lt;br /&gt;
&lt;br /&gt;
Some of your classes are in &amp;lt;code&amp;gt;examplemod.*&amp;lt;/code&amp;gt;. Move them to a unique package.&lt;br /&gt;
&lt;br /&gt;
== Next steps ==&lt;br /&gt;
Once your mod loads successfully, you can start adding actual content and logic. A good first milestone is:&lt;br /&gt;
&lt;br /&gt;
Confirm the game loads your jar with no errors.&lt;br /&gt;
&lt;br /&gt;
Add one small change at a time (so you know what broke if something stops loading).&lt;br /&gt;
&lt;br /&gt;
{{Tip&lt;br /&gt;
|title=Keep it simple while learning&lt;br /&gt;
|text=The easiest way to learn modding is to keep each step small: get the mod to load, then add one feature, test, repeat.&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Jamesp1989</name></author>
	</entry>
	<entry>
		<id>https://necessewiki.com/mediawiki/index.php?title=Modding/draft&amp;diff=24681</id>
		<title>Modding/draft</title>
		<link rel="alternate" type="text/html" href="https://necessewiki.com/mediawiki/index.php?title=Modding/draft&amp;diff=24681"/>
		<updated>2026-01-16T07:49:21Z</updated>

		<summary type="html">&lt;p&gt;Jamesp1989: /* Step 4: Build the jar with the correct contents */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{ItemList&lt;br /&gt;
|compact&lt;br /&gt;
|&lt;br /&gt;
What this guide covers&lt;br /&gt;
|This is a beginner-focused guide to making a Necesse mod, based on what the game’s mod loader requires for a mod to be considered valid. It focuses on getting a mod to load successfully&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
= Beginner Guide: Making a Necesse Mod =&lt;br /&gt;
== What the game considers a “valid” mod ==&lt;br /&gt;
To be loaded by the game, your mod must meet these requirements:&lt;br /&gt;
{{ItemList|compact|&lt;br /&gt;
|&lt;br /&gt;
# &#039;&#039;&#039;It must be a &amp;lt;code&amp;gt;.jar&amp;lt;/code&amp;gt; file.&#039;&#039;&#039;&lt;br /&gt;
# &#039;&#039;&#039;The jar must contain a &amp;lt;code&amp;gt;mod.info&amp;lt;/code&amp;gt; file at the root of the jar.&#039;&#039;&#039;&lt;br /&gt;
# &#039;&#039;&#039;The &amp;lt;code&amp;gt;mod.info&amp;lt;/code&amp;gt; must include required fields&#039;&#039;&#039; (see below).&lt;br /&gt;
# &#039;&#039;&#039;The jar must contain exactly one mod entry class&#039;&#039;&#039; annotated with &amp;lt;code&amp;gt;@ModEntry&amp;lt;/code&amp;gt;.&lt;br /&gt;
# &#039;&#039;&#039;The mod entry class must have a public no-argument constructor.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
If any of these are missing, the loader will reject the mod or log an error.&lt;br /&gt;
}}&lt;br /&gt;
== Step 1: Pick a unique Java package ==&lt;br /&gt;
{{ItemList|compact|&lt;br /&gt;
|Before writing any code, choose a unique Java package name for your mod.&lt;br /&gt;
&lt;br /&gt;
Avoid using:&lt;br /&gt;
* &amp;lt;code&amp;gt;examplemod&amp;lt;/code&amp;gt; (the loader warns about this)&lt;br /&gt;
* &amp;lt;code&amp;gt;necesse&amp;lt;/code&amp;gt; (reserved for the base game)&lt;br /&gt;
* the default package (no package)&lt;br /&gt;
&lt;br /&gt;
Use something unique, for example:&lt;br /&gt;
* &amp;lt;code&amp;gt;com.yourname.yourmod&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;If your mod contains classes in the &amp;lt;code&amp;gt;examplemod&amp;lt;/code&amp;gt; package, the loader will log a warning. In dev mod loading it specifically warns that you must move packages to upload, and in normal loading it warns that this will likely not be allowed in future versions.&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
== Step 2: Create the mod.info file ==&lt;br /&gt;
{{ItemList|compact|&lt;br /&gt;
|&lt;br /&gt;
Create a plain text file named &amp;lt;code&amp;gt;mod.info&amp;lt;/code&amp;gt;. This file must be included in the jar at the &#039;&#039;&#039;root&#039;&#039;&#039; (top level).&lt;br /&gt;
&lt;br /&gt;
=== Required fields ===&lt;br /&gt;
The loader requires these fields to exist and not be empty:&lt;br /&gt;
* &amp;lt;code&amp;gt;id&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;version&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;gameVersion&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;author&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;description&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Optional fields ===&lt;br /&gt;
These are supported by the loader and are commonly included:&lt;br /&gt;
* &amp;lt;code&amp;gt;clientside&amp;lt;/code&amp;gt; (boolean)&lt;br /&gt;
* &amp;lt;code&amp;gt;dependencies&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;optionalDependencies&amp;lt;/code&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
=== Example mod.info ===&lt;br /&gt;
 id = &amp;quot;mytestmod&amp;quot;&lt;br /&gt;
 name = &amp;quot;My Test Mod&amp;quot;&lt;br /&gt;
 version = &amp;quot;1.0&amp;quot;&lt;br /&gt;
 gameVersion = &amp;quot;1.1.1&amp;quot;&lt;br /&gt;
 author = &amp;quot;YourName&amp;quot;&lt;br /&gt;
 description = &amp;quot;A beginner test mod.&amp;quot;&lt;br /&gt;
 clientside = false&lt;br /&gt;
 dependencies = []&lt;br /&gt;
 optionalDependencies = []&lt;br /&gt;
&lt;br /&gt;
{{ItemList|compact|&lt;br /&gt;
|The loader validates the format of &amp;lt;code&amp;gt;id&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;version&amp;lt;/code&amp;gt;. If you use strange characters or invalid version formatting, the mod can be rejected. Keep them simple (letters/numbers, dots, dashes).&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Step 3: Create your Mod Entry class ==&lt;br /&gt;
{{ItemList|compact|&lt;br /&gt;
|&lt;br /&gt;
A mod must have &#039;&#039;&#039;exactly one&#039;&#039;&#039; “entry point” class marked with the &amp;lt;code&amp;gt;@ModEntry&amp;lt;/code&amp;gt; annotation.&lt;br /&gt;
&lt;br /&gt;
Rules:&lt;br /&gt;
&lt;br /&gt;
If the loader finds &#039;&#039;&#039;no&#039;&#039;&#039; &amp;lt;code&amp;gt;@ModEntry&amp;lt;/code&amp;gt; class, the mod will not load.&lt;br /&gt;
&lt;br /&gt;
If the loader finds &#039;&#039;&#039;more than one&#039;&#039;&#039; &amp;lt;code&amp;gt;@ModEntry&amp;lt;/code&amp;gt; class, it errors.&lt;br /&gt;
&lt;br /&gt;
The class must have a &#039;&#039;&#039;public no-argument constructor&#039;&#039;&#039; because the loader creates it at runtime&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Minimal example ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=Java&amp;gt;&lt;br /&gt;
import necesse.engine.modLoader.annotations.ModEntry;&lt;br /&gt;
&lt;br /&gt;
@ModEntry&lt;br /&gt;
public class MyTestMod {&lt;br /&gt;
    public MyTestMod() {&lt;br /&gt;
        // Public no-arg constructor required by the loader&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Step 4: Build the jar with the correct contents ==&lt;br /&gt;
When you build your mod, the final &amp;lt;code&amp;gt;.jar&amp;lt;/code&amp;gt; must contain:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/mod.info&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Your compiled class files, including the entry class&lt;br /&gt;
&lt;br /&gt;
A simple “jar contents” checklist:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/mod.info&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;/com/yourname/mytestmod/MyTestMod.class&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Optional: Mod lifecycle methods ==&lt;br /&gt;
The loader can call lifecycle methods on your mod entry class &#039;&#039;&#039;if they exist&#039;&#039;&#039;. If they do not exist, the loader simply skips them.&lt;br /&gt;
&lt;br /&gt;
Common lifecycle method names include:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;preInit()&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;init()&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;initResources()&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;postInit()&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;initSettings()&amp;lt;/code&amp;gt; (special case: if present, it must return a &amp;lt;code&amp;gt;ModSettings&amp;lt;/code&amp;gt; type)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dispose()&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Tip&lt;br /&gt;
|title=Beginner recommendation&lt;br /&gt;
|text=Start with only &amp;lt;code&amp;gt;mod.info&amp;lt;/code&amp;gt; and an empty &amp;lt;code&amp;gt;@ModEntry&amp;lt;/code&amp;gt; class first. Once the game loads your mod successfully, add features step-by-step.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
=== “Did not contain a mod.info file” ===&lt;br /&gt;
&lt;br /&gt;
Your jar is missing &amp;lt;code&amp;gt;mod.info&amp;lt;/code&amp;gt;, or it is not at the root of the jar.&lt;br /&gt;
&lt;br /&gt;
=== Mod is ignored / not loaded ===&lt;br /&gt;
&lt;br /&gt;
The file is not a &amp;lt;code&amp;gt;.jar&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The jar does not contain a valid &amp;lt;code&amp;gt;mod.info&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
No &amp;lt;code&amp;gt;@ModEntry&amp;lt;/code&amp;gt; class was found.&lt;br /&gt;
&lt;br /&gt;
=== Error about @ModEntry being used multiple times ===&lt;br /&gt;
&lt;br /&gt;
More than one class in your jar has &amp;lt;code&amp;gt;@ModEntry&amp;lt;/code&amp;gt;. You must have exactly one.&lt;br /&gt;
&lt;br /&gt;
=== Entry class fails to construct ===&lt;br /&gt;
&lt;br /&gt;
Your entry class does not have a public no-argument constructor.&lt;br /&gt;
&lt;br /&gt;
=== Warning about examplemod package ===&lt;br /&gt;
&lt;br /&gt;
Some of your classes are in &amp;lt;code&amp;gt;examplemod.*&amp;lt;/code&amp;gt;. Move them to a unique package.&lt;br /&gt;
&lt;br /&gt;
== Next steps ==&lt;br /&gt;
Once your mod loads successfully, you can start adding actual content and logic. A good first milestone is:&lt;br /&gt;
&lt;br /&gt;
Confirm the game loads your jar with no errors.&lt;br /&gt;
&lt;br /&gt;
Add one small change at a time (so you know what broke if something stops loading).&lt;br /&gt;
&lt;br /&gt;
{{Tip&lt;br /&gt;
|title=Keep it simple while learning&lt;br /&gt;
|text=The easiest way to learn modding is to keep each step small: get the mod to load, then add one feature, test, repeat.&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Jamesp1989</name></author>
	</entry>
	<entry>
		<id>https://necessewiki.com/mediawiki/index.php?title=Modding/draft&amp;diff=24680</id>
		<title>Modding/draft</title>
		<link rel="alternate" type="text/html" href="https://necessewiki.com/mediawiki/index.php?title=Modding/draft&amp;diff=24680"/>
		<updated>2026-01-16T07:48:15Z</updated>

		<summary type="html">&lt;p&gt;Jamesp1989: /* Minimal example */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{ItemList&lt;br /&gt;
|compact&lt;br /&gt;
|&lt;br /&gt;
What this guide covers&lt;br /&gt;
|This is a beginner-focused guide to making a Necesse mod, based on what the game’s mod loader requires for a mod to be considered valid. It focuses on getting a mod to load successfully&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
= Beginner Guide: Making a Necesse Mod =&lt;br /&gt;
== What the game considers a “valid” mod ==&lt;br /&gt;
To be loaded by the game, your mod must meet these requirements:&lt;br /&gt;
{{ItemList|compact|&lt;br /&gt;
|&lt;br /&gt;
# &#039;&#039;&#039;It must be a &amp;lt;code&amp;gt;.jar&amp;lt;/code&amp;gt; file.&#039;&#039;&#039;&lt;br /&gt;
# &#039;&#039;&#039;The jar must contain a &amp;lt;code&amp;gt;mod.info&amp;lt;/code&amp;gt; file at the root of the jar.&#039;&#039;&#039;&lt;br /&gt;
# &#039;&#039;&#039;The &amp;lt;code&amp;gt;mod.info&amp;lt;/code&amp;gt; must include required fields&#039;&#039;&#039; (see below).&lt;br /&gt;
# &#039;&#039;&#039;The jar must contain exactly one mod entry class&#039;&#039;&#039; annotated with &amp;lt;code&amp;gt;@ModEntry&amp;lt;/code&amp;gt;.&lt;br /&gt;
# &#039;&#039;&#039;The mod entry class must have a public no-argument constructor.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
If any of these are missing, the loader will reject the mod or log an error.&lt;br /&gt;
}}&lt;br /&gt;
== Step 1: Pick a unique Java package ==&lt;br /&gt;
{{ItemList|compact|&lt;br /&gt;
|Before writing any code, choose a unique Java package name for your mod.&lt;br /&gt;
&lt;br /&gt;
Avoid using:&lt;br /&gt;
* &amp;lt;code&amp;gt;examplemod&amp;lt;/code&amp;gt; (the loader warns about this)&lt;br /&gt;
* &amp;lt;code&amp;gt;necesse&amp;lt;/code&amp;gt; (reserved for the base game)&lt;br /&gt;
* the default package (no package)&lt;br /&gt;
&lt;br /&gt;
Use something unique, for example:&lt;br /&gt;
* &amp;lt;code&amp;gt;com.yourname.yourmod&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;If your mod contains classes in the &amp;lt;code&amp;gt;examplemod&amp;lt;/code&amp;gt; package, the loader will log a warning. In dev mod loading it specifically warns that you must move packages to upload, and in normal loading it warns that this will likely not be allowed in future versions.&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
== Step 2: Create the mod.info file ==&lt;br /&gt;
{{ItemList|compact|&lt;br /&gt;
|&lt;br /&gt;
Create a plain text file named &amp;lt;code&amp;gt;mod.info&amp;lt;/code&amp;gt;. This file must be included in the jar at the &#039;&#039;&#039;root&#039;&#039;&#039; (top level).&lt;br /&gt;
&lt;br /&gt;
=== Required fields ===&lt;br /&gt;
The loader requires these fields to exist and not be empty:&lt;br /&gt;
* &amp;lt;code&amp;gt;id&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;version&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;gameVersion&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;author&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;description&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Optional fields ===&lt;br /&gt;
These are supported by the loader and are commonly included:&lt;br /&gt;
* &amp;lt;code&amp;gt;clientside&amp;lt;/code&amp;gt; (boolean)&lt;br /&gt;
* &amp;lt;code&amp;gt;dependencies&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;optionalDependencies&amp;lt;/code&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
=== Example mod.info ===&lt;br /&gt;
 id = &amp;quot;mytestmod&amp;quot;&lt;br /&gt;
 name = &amp;quot;My Test Mod&amp;quot;&lt;br /&gt;
 version = &amp;quot;1.0&amp;quot;&lt;br /&gt;
 gameVersion = &amp;quot;1.1.1&amp;quot;&lt;br /&gt;
 author = &amp;quot;YourName&amp;quot;&lt;br /&gt;
 description = &amp;quot;A beginner test mod.&amp;quot;&lt;br /&gt;
 clientside = false&lt;br /&gt;
 dependencies = []&lt;br /&gt;
 optionalDependencies = []&lt;br /&gt;
&lt;br /&gt;
{{ItemList|compact|&lt;br /&gt;
|The loader validates the format of &amp;lt;code&amp;gt;id&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;version&amp;lt;/code&amp;gt;. If you use strange characters or invalid version formatting, the mod can be rejected. Keep them simple (letters/numbers, dots, dashes).&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Step 3: Create your Mod Entry class ==&lt;br /&gt;
{{ItemList|compact|&lt;br /&gt;
|&lt;br /&gt;
A mod must have &#039;&#039;&#039;exactly one&#039;&#039;&#039; “entry point” class marked with the &amp;lt;code&amp;gt;@ModEntry&amp;lt;/code&amp;gt; annotation.&lt;br /&gt;
&lt;br /&gt;
Rules:&lt;br /&gt;
&lt;br /&gt;
If the loader finds &#039;&#039;&#039;no&#039;&#039;&#039; &amp;lt;code&amp;gt;@ModEntry&amp;lt;/code&amp;gt; class, the mod will not load.&lt;br /&gt;
&lt;br /&gt;
If the loader finds &#039;&#039;&#039;more than one&#039;&#039;&#039; &amp;lt;code&amp;gt;@ModEntry&amp;lt;/code&amp;gt; class, it errors.&lt;br /&gt;
&lt;br /&gt;
The class must have a &#039;&#039;&#039;public no-argument constructor&#039;&#039;&#039; because the loader creates it at runtime&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Minimal example ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=Java&amp;gt;&lt;br /&gt;
import necesse.engine.modLoader.annotations.ModEntry;&lt;br /&gt;
&lt;br /&gt;
@ModEntry&lt;br /&gt;
public class MyTestMod {&lt;br /&gt;
    public MyTestMod() {&lt;br /&gt;
        // Public no-arg constructor required by the loader&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Step 4: Build the jar with the correct contents ==&lt;br /&gt;
When you build your mod, the final &amp;lt;code&amp;gt;.jar&amp;lt;/code&amp;gt; must contain:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/mod.info&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Your compiled class files, including the entry class&lt;br /&gt;
&lt;br /&gt;
A simple “jar contents” checklist:&lt;br /&gt;
&lt;br /&gt;
✅ &amp;lt;code&amp;gt;/mod.info&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
✅ &amp;lt;code&amp;gt;/com/yourname/mytestmod/MyTestMod.class&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Optional: Mod lifecycle methods ==&lt;br /&gt;
The loader can call lifecycle methods on your mod entry class &#039;&#039;&#039;if they exist&#039;&#039;&#039;. If they do not exist, the loader simply skips them.&lt;br /&gt;
&lt;br /&gt;
Common lifecycle method names include:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;preInit()&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;init()&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;initResources()&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;postInit()&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;initSettings()&amp;lt;/code&amp;gt; (special case: if present, it must return a &amp;lt;code&amp;gt;ModSettings&amp;lt;/code&amp;gt; type)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dispose()&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Tip&lt;br /&gt;
|title=Beginner recommendation&lt;br /&gt;
|text=Start with only &amp;lt;code&amp;gt;mod.info&amp;lt;/code&amp;gt; and an empty &amp;lt;code&amp;gt;@ModEntry&amp;lt;/code&amp;gt; class first. Once the game loads your mod successfully, add features step-by-step.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
=== “Did not contain a mod.info file” ===&lt;br /&gt;
&lt;br /&gt;
Your jar is missing &amp;lt;code&amp;gt;mod.info&amp;lt;/code&amp;gt;, or it is not at the root of the jar.&lt;br /&gt;
&lt;br /&gt;
=== Mod is ignored / not loaded ===&lt;br /&gt;
&lt;br /&gt;
The file is not a &amp;lt;code&amp;gt;.jar&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The jar does not contain a valid &amp;lt;code&amp;gt;mod.info&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
No &amp;lt;code&amp;gt;@ModEntry&amp;lt;/code&amp;gt; class was found.&lt;br /&gt;
&lt;br /&gt;
=== Error about @ModEntry being used multiple times ===&lt;br /&gt;
&lt;br /&gt;
More than one class in your jar has &amp;lt;code&amp;gt;@ModEntry&amp;lt;/code&amp;gt;. You must have exactly one.&lt;br /&gt;
&lt;br /&gt;
=== Entry class fails to construct ===&lt;br /&gt;
&lt;br /&gt;
Your entry class does not have a public no-argument constructor.&lt;br /&gt;
&lt;br /&gt;
=== Warning about examplemod package ===&lt;br /&gt;
&lt;br /&gt;
Some of your classes are in &amp;lt;code&amp;gt;examplemod.*&amp;lt;/code&amp;gt;. Move them to a unique package.&lt;br /&gt;
&lt;br /&gt;
== Next steps ==&lt;br /&gt;
Once your mod loads successfully, you can start adding actual content and logic. A good first milestone is:&lt;br /&gt;
&lt;br /&gt;
Confirm the game loads your jar with no errors.&lt;br /&gt;
&lt;br /&gt;
Add one small change at a time (so you know what broke if something stops loading).&lt;br /&gt;
&lt;br /&gt;
{{Tip&lt;br /&gt;
|title=Keep it simple while learning&lt;br /&gt;
|text=The easiest way to learn modding is to keep each step small: get the mod to load, then add one feature, test, repeat.&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Jamesp1989</name></author>
	</entry>
	<entry>
		<id>https://necessewiki.com/mediawiki/index.php?title=Modding/draft&amp;diff=24679</id>
		<title>Modding/draft</title>
		<link rel="alternate" type="text/html" href="https://necessewiki.com/mediawiki/index.php?title=Modding/draft&amp;diff=24679"/>
		<updated>2026-01-16T07:46:44Z</updated>

		<summary type="html">&lt;p&gt;Jamesp1989: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{ItemList&lt;br /&gt;
|compact&lt;br /&gt;
|&lt;br /&gt;
What this guide covers&lt;br /&gt;
|This is a beginner-focused guide to making a Necesse mod, based on what the game’s mod loader requires for a mod to be considered valid. It focuses on getting a mod to load successfully&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
= Beginner Guide: Making a Necesse Mod =&lt;br /&gt;
== What the game considers a “valid” mod ==&lt;br /&gt;
To be loaded by the game, your mod must meet these requirements:&lt;br /&gt;
{{ItemList|compact|&lt;br /&gt;
|&lt;br /&gt;
# &#039;&#039;&#039;It must be a &amp;lt;code&amp;gt;.jar&amp;lt;/code&amp;gt; file.&#039;&#039;&#039;&lt;br /&gt;
# &#039;&#039;&#039;The jar must contain a &amp;lt;code&amp;gt;mod.info&amp;lt;/code&amp;gt; file at the root of the jar.&#039;&#039;&#039;&lt;br /&gt;
# &#039;&#039;&#039;The &amp;lt;code&amp;gt;mod.info&amp;lt;/code&amp;gt; must include required fields&#039;&#039;&#039; (see below).&lt;br /&gt;
# &#039;&#039;&#039;The jar must contain exactly one mod entry class&#039;&#039;&#039; annotated with &amp;lt;code&amp;gt;@ModEntry&amp;lt;/code&amp;gt;.&lt;br /&gt;
# &#039;&#039;&#039;The mod entry class must have a public no-argument constructor.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
If any of these are missing, the loader will reject the mod or log an error.&lt;br /&gt;
}}&lt;br /&gt;
== Step 1: Pick a unique Java package ==&lt;br /&gt;
{{ItemList|compact|&lt;br /&gt;
|Before writing any code, choose a unique Java package name for your mod.&lt;br /&gt;
&lt;br /&gt;
Avoid using:&lt;br /&gt;
* &amp;lt;code&amp;gt;examplemod&amp;lt;/code&amp;gt; (the loader warns about this)&lt;br /&gt;
* &amp;lt;code&amp;gt;necesse&amp;lt;/code&amp;gt; (reserved for the base game)&lt;br /&gt;
* the default package (no package)&lt;br /&gt;
&lt;br /&gt;
Use something unique, for example:&lt;br /&gt;
* &amp;lt;code&amp;gt;com.yourname.yourmod&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;If your mod contains classes in the &amp;lt;code&amp;gt;examplemod&amp;lt;/code&amp;gt; package, the loader will log a warning. In dev mod loading it specifically warns that you must move packages to upload, and in normal loading it warns that this will likely not be allowed in future versions.&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
== Step 2: Create the mod.info file ==&lt;br /&gt;
{{ItemList|compact|&lt;br /&gt;
|&lt;br /&gt;
Create a plain text file named &amp;lt;code&amp;gt;mod.info&amp;lt;/code&amp;gt;. This file must be included in the jar at the &#039;&#039;&#039;root&#039;&#039;&#039; (top level).&lt;br /&gt;
&lt;br /&gt;
=== Required fields ===&lt;br /&gt;
The loader requires these fields to exist and not be empty:&lt;br /&gt;
* &amp;lt;code&amp;gt;id&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;version&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;gameVersion&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;author&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;description&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Optional fields ===&lt;br /&gt;
These are supported by the loader and are commonly included:&lt;br /&gt;
* &amp;lt;code&amp;gt;clientside&amp;lt;/code&amp;gt; (boolean)&lt;br /&gt;
* &amp;lt;code&amp;gt;dependencies&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;optionalDependencies&amp;lt;/code&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
=== Example mod.info ===&lt;br /&gt;
 id = &amp;quot;mytestmod&amp;quot;&lt;br /&gt;
 name = &amp;quot;My Test Mod&amp;quot;&lt;br /&gt;
 version = &amp;quot;1.0&amp;quot;&lt;br /&gt;
 gameVersion = &amp;quot;1.1.1&amp;quot;&lt;br /&gt;
 author = &amp;quot;YourName&amp;quot;&lt;br /&gt;
 description = &amp;quot;A beginner test mod.&amp;quot;&lt;br /&gt;
 clientside = false&lt;br /&gt;
 dependencies = []&lt;br /&gt;
 optionalDependencies = []&lt;br /&gt;
&lt;br /&gt;
{{ItemList|compact|&lt;br /&gt;
|The loader validates the format of &amp;lt;code&amp;gt;id&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;version&amp;lt;/code&amp;gt;. If you use strange characters or invalid version formatting, the mod can be rejected. Keep them simple (letters/numbers, dots, dashes).&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Step 3: Create your Mod Entry class ==&lt;br /&gt;
{{ItemList|compact|&lt;br /&gt;
|&lt;br /&gt;
A mod must have &#039;&#039;&#039;exactly one&#039;&#039;&#039; “entry point” class marked with the &amp;lt;code&amp;gt;@ModEntry&amp;lt;/code&amp;gt; annotation.&lt;br /&gt;
&lt;br /&gt;
Rules:&lt;br /&gt;
&lt;br /&gt;
If the loader finds &#039;&#039;&#039;no&#039;&#039;&#039; &amp;lt;code&amp;gt;@ModEntry&amp;lt;/code&amp;gt; class, the mod will not load.&lt;br /&gt;
&lt;br /&gt;
If the loader finds &#039;&#039;&#039;more than one&#039;&#039;&#039; &amp;lt;code&amp;gt;@ModEntry&amp;lt;/code&amp;gt; class, it errors.&lt;br /&gt;
&lt;br /&gt;
The class must have a &#039;&#039;&#039;public no-argument constructor&#039;&#039;&#039; because the loader creates it at runtime&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Minimal example ===&lt;br /&gt;
{{ItemList|compact|&lt;br /&gt;
|&lt;br /&gt;
import necesse.engine.modLoader.annotations.ModEntry;&lt;br /&gt;
&lt;br /&gt;
@ModEntry&lt;br /&gt;
public class MyTestMod {&lt;br /&gt;
    public MyTestMod() {&lt;br /&gt;
        // Public no-arg constructor required by the loader&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
}}&lt;br /&gt;
== Step 4: Build the jar with the correct contents ==&lt;br /&gt;
When you build your mod, the final &amp;lt;code&amp;gt;.jar&amp;lt;/code&amp;gt; must contain:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/mod.info&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Your compiled class files, including the entry class&lt;br /&gt;
&lt;br /&gt;
A simple “jar contents” checklist:&lt;br /&gt;
&lt;br /&gt;
✅ &amp;lt;code&amp;gt;/mod.info&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
✅ &amp;lt;code&amp;gt;/com/yourname/mytestmod/MyTestMod.class&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Optional: Mod lifecycle methods ==&lt;br /&gt;
The loader can call lifecycle methods on your mod entry class &#039;&#039;&#039;if they exist&#039;&#039;&#039;. If they do not exist, the loader simply skips them.&lt;br /&gt;
&lt;br /&gt;
Common lifecycle method names include:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;preInit()&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;init()&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;initResources()&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;postInit()&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;initSettings()&amp;lt;/code&amp;gt; (special case: if present, it must return a &amp;lt;code&amp;gt;ModSettings&amp;lt;/code&amp;gt; type)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dispose()&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Tip&lt;br /&gt;
|title=Beginner recommendation&lt;br /&gt;
|text=Start with only &amp;lt;code&amp;gt;mod.info&amp;lt;/code&amp;gt; and an empty &amp;lt;code&amp;gt;@ModEntry&amp;lt;/code&amp;gt; class first. Once the game loads your mod successfully, add features step-by-step.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
=== “Did not contain a mod.info file” ===&lt;br /&gt;
&lt;br /&gt;
Your jar is missing &amp;lt;code&amp;gt;mod.info&amp;lt;/code&amp;gt;, or it is not at the root of the jar.&lt;br /&gt;
&lt;br /&gt;
=== Mod is ignored / not loaded ===&lt;br /&gt;
&lt;br /&gt;
The file is not a &amp;lt;code&amp;gt;.jar&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The jar does not contain a valid &amp;lt;code&amp;gt;mod.info&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
No &amp;lt;code&amp;gt;@ModEntry&amp;lt;/code&amp;gt; class was found.&lt;br /&gt;
&lt;br /&gt;
=== Error about @ModEntry being used multiple times ===&lt;br /&gt;
&lt;br /&gt;
More than one class in your jar has &amp;lt;code&amp;gt;@ModEntry&amp;lt;/code&amp;gt;. You must have exactly one.&lt;br /&gt;
&lt;br /&gt;
=== Entry class fails to construct ===&lt;br /&gt;
&lt;br /&gt;
Your entry class does not have a public no-argument constructor.&lt;br /&gt;
&lt;br /&gt;
=== Warning about examplemod package ===&lt;br /&gt;
&lt;br /&gt;
Some of your classes are in &amp;lt;code&amp;gt;examplemod.*&amp;lt;/code&amp;gt;. Move them to a unique package.&lt;br /&gt;
&lt;br /&gt;
== Next steps ==&lt;br /&gt;
Once your mod loads successfully, you can start adding actual content and logic. A good first milestone is:&lt;br /&gt;
&lt;br /&gt;
Confirm the game loads your jar with no errors.&lt;br /&gt;
&lt;br /&gt;
Add one small change at a time (so you know what broke if something stops loading).&lt;br /&gt;
&lt;br /&gt;
{{Tip&lt;br /&gt;
|title=Keep it simple while learning&lt;br /&gt;
|text=The easiest way to learn modding is to keep each step small: get the mod to load, then add one feature, test, repeat.&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Jamesp1989</name></author>
	</entry>
	<entry>
		<id>https://necessewiki.com/mediawiki/index.php?title=User:Jamesp1989/common.js&amp;diff=24678</id>
		<title>User:Jamesp1989/common.js</title>
		<link rel="alternate" type="text/html" href="https://necessewiki.com/mediawiki/index.php?title=User:Jamesp1989/common.js&amp;diff=24678"/>
		<updated>2026-01-16T05:18:18Z</updated>

		<summary type="html">&lt;p&gt;Jamesp1989: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
	&amp;quot;Enclose with nowiki&amp;quot;: {&lt;br /&gt;
		&amp;quot;wt2html&amp;quot;: &amp;quot;&amp;lt;p data-parsoid=&#039;{\&amp;quot;dsr\&amp;quot;:[0,69,0,0]}&#039;&amp;gt;&amp;lt;code class=\&amp;quot;mw-highlight mw-highlight-lang-text mw-content-ltr\&amp;quot; dir=\&amp;quot;ltr\&amp;quot; typeof=\&amp;quot;mw:Extension/syntaxhighlight mw:Transclusion\&amp;quot; about=\&amp;quot;#mwt2\&amp;quot; data-parsoid=&#039;{\&amp;quot;pi\&amp;quot;:[[{\&amp;quot;k\&amp;quot;:\&amp;quot;1\&amp;quot;},{\&amp;quot;k\&amp;quot;:\&amp;quot;lang\&amp;quot;,\&amp;quot;named\&amp;quot;:true},{\&amp;quot;k\&amp;quot;:\&amp;quot;inline\&amp;quot;,\&amp;quot;named\&amp;quot;:true}]],\&amp;quot;dsr\&amp;quot;:[0,69,null,null]}&#039; data-mw=&#039;{\&amp;quot;parts\&amp;quot;:[{\&amp;quot;template\&amp;quot;:{\&amp;quot;target\&amp;quot;:{\&amp;quot;wt\&amp;quot;:\&amp;quot;#tag:syntaxhighlight\&amp;quot;,\&amp;quot;function\&amp;quot;:\&amp;quot;tag\&amp;quot;},\&amp;quot;params\&amp;quot;:{\&amp;quot;1\&amp;quot;:{\&amp;quot;wt\&amp;quot;:\&amp;quot;&amp;amp;lt;nowiki&amp;gt;foo&amp;amp;lt;/nowiki&amp;gt;\&amp;quot;},\&amp;quot;lang\&amp;quot;:{\&amp;quot;wt\&amp;quot;:\&amp;quot;\\\&amp;quot;text\\\&amp;quot;\&amp;quot;},\&amp;quot;inline\&amp;quot;:{\&amp;quot;wt\&amp;quot;:\&amp;quot;none\&amp;quot;}},\&amp;quot;i\&amp;quot;:0}}]}&#039;&amp;gt;&amp;amp;lt;nowiki&amp;gt;foo&amp;amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&amp;lt;/p&amp;gt;&amp;quot;,&lt;br /&gt;
		&amp;quot;html2html&amp;quot;: &amp;quot;&amp;lt;p data-parsoid=&#039;{\&amp;quot;dsr\&amp;quot;:[0,69,0,0]}&#039;&amp;gt;&amp;lt;code class=\&amp;quot;mw-highlight mw-highlight-lang-text mw-content-ltr\&amp;quot; dir=\&amp;quot;ltr\&amp;quot; typeof=\&amp;quot;mw:Extension/syntaxhighlight mw:Transclusion\&amp;quot; about=\&amp;quot;#mwt2\&amp;quot; data-parsoid=&#039;{\&amp;quot;pi\&amp;quot;:[[{\&amp;quot;k\&amp;quot;:\&amp;quot;1\&amp;quot;},{\&amp;quot;k\&amp;quot;:\&amp;quot;lang\&amp;quot;,\&amp;quot;named\&amp;quot;:true},{\&amp;quot;k\&amp;quot;:\&amp;quot;inline\&amp;quot;,\&amp;quot;named\&amp;quot;:true}]],\&amp;quot;dsr\&amp;quot;:[0,69,null,null]}&#039; data-mw=&#039;{\&amp;quot;parts\&amp;quot;:[{\&amp;quot;template\&amp;quot;:{\&amp;quot;target\&amp;quot;:{\&amp;quot;wt\&amp;quot;:\&amp;quot;#tag:syntaxhighlight\&amp;quot;,\&amp;quot;function\&amp;quot;:\&amp;quot;tag\&amp;quot;},\&amp;quot;params\&amp;quot;:{\&amp;quot;1\&amp;quot;:{\&amp;quot;wt\&amp;quot;:\&amp;quot;&amp;amp;lt;nowiki&amp;gt;foo&amp;amp;lt;/nowiki&amp;gt;\&amp;quot;},\&amp;quot;lang\&amp;quot;:{\&amp;quot;wt\&amp;quot;:\&amp;quot;\\\&amp;quot;text\\\&amp;quot;\&amp;quot;},\&amp;quot;inline\&amp;quot;:{\&amp;quot;wt\&amp;quot;:\&amp;quot;none\&amp;quot;}},\&amp;quot;i\&amp;quot;:0}}]}&#039;&amp;gt;&amp;amp;lt;nowiki&amp;gt;foo&amp;amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&amp;lt;/p&amp;gt;&amp;quot;&lt;br /&gt;
	},&lt;br /&gt;
	&amp;quot;Inline attribute (inline code)&amp;quot;: {&lt;br /&gt;
		&amp;quot;wt2wt&amp;quot;: &amp;quot;Text &amp;lt;source lang=\&amp;quot;javascript\&amp;quot; inline=\&amp;quot;\&amp;quot;&amp;gt;var a;&amp;lt;/source&amp;gt;.&amp;quot;,&lt;br /&gt;
		&amp;quot;selser [1]&amp;quot;: &amp;quot;Text &amp;lt;source lang=\&amp;quot;javascript\&amp;quot; inline&amp;gt;var a;&amp;lt;/source&amp;gt;.&amp;quot;,&lt;br /&gt;
		&amp;quot;selser [[4,0,4]]&amp;quot;: &amp;quot;121y1t4&amp;lt;source lang=\&amp;quot;javascript\&amp;quot; inline&amp;gt;var a;&amp;lt;/source&amp;gt;1ibg90y&amp;quot;,&lt;br /&gt;
		&amp;quot;selser [[0,0,2]]&amp;quot;: &amp;quot;Text &amp;lt;source lang=\&amp;quot;javascript\&amp;quot; inline&amp;gt;var a;&amp;lt;/source&amp;gt;yeuqlm.&amp;quot;,&lt;br /&gt;
		&amp;quot;selser [2]&amp;quot;: &amp;quot;brhsc5\n\nText &amp;lt;source lang=\&amp;quot;javascript\&amp;quot; inline&amp;gt;var a;&amp;lt;/source&amp;gt;.&amp;quot;,&lt;br /&gt;
		&amp;quot;selser [[0,0,4]]&amp;quot;: &amp;quot;Text &amp;lt;source lang=\&amp;quot;javascript\&amp;quot; inline&amp;gt;var a;&amp;lt;/source&amp;gt;4x62b6&amp;quot;,&lt;br /&gt;
		&amp;quot;selser [[2,0,0]]&amp;quot;: &amp;quot;1mjitw8Text &amp;lt;source lang=\&amp;quot;javascript\&amp;quot; inline&amp;gt;var a;&amp;lt;/source&amp;gt;.&amp;quot;,&lt;br /&gt;
		&amp;quot;selser [[0,0,3]]&amp;quot;: &amp;quot;Text &amp;lt;source lang=\&amp;quot;javascript\&amp;quot; inline&amp;gt;var a;&amp;lt;/source&amp;gt;&amp;quot;,&lt;br /&gt;
		&amp;quot;selser [[2,0,4]]&amp;quot;: &amp;quot;uuwnfvText &amp;lt;source lang=\&amp;quot;javascript\&amp;quot; inline&amp;gt;var a;&amp;lt;/source&amp;gt;qjkvx1&amp;quot;,&lt;br /&gt;
		&amp;quot;selser [[3,0,3]]&amp;quot;: &amp;quot;&amp;lt;source lang=\&amp;quot;javascript\&amp;quot; inline&amp;gt;var a;&amp;lt;/source&amp;gt;&amp;quot;,&lt;br /&gt;
		&amp;quot;selser [[4,0,0]]&amp;quot;: &amp;quot;uouej0&amp;lt;source lang=\&amp;quot;javascript\&amp;quot; inline&amp;gt;var a;&amp;lt;/source&amp;gt;.&amp;quot;,&lt;br /&gt;
		&amp;quot;selser [[3,0,0]]&amp;quot;: &amp;quot;&amp;lt;source lang=\&amp;quot;javascript\&amp;quot; inline&amp;gt;var a;&amp;lt;/source&amp;gt;.&amp;quot;,&lt;br /&gt;
		&amp;quot;selser [[4,0,3]]&amp;quot;: &amp;quot;1wcoh54&amp;lt;source lang=\&amp;quot;javascript\&amp;quot; inline&amp;gt;var a;&amp;lt;/source&amp;gt;&amp;quot;,&lt;br /&gt;
		&amp;quot;selser [[2,0,2]]&amp;quot;: &amp;quot;11th7ozText &amp;lt;source lang=\&amp;quot;javascript\&amp;quot; inline&amp;gt;var a;&amp;lt;/source&amp;gt;1c8ff9m.&amp;quot;,&lt;br /&gt;
		&amp;quot;selser [[2,0,3]]&amp;quot;: &amp;quot;1cyv6rText &amp;lt;source lang=\&amp;quot;javascript\&amp;quot; inline&amp;gt;var a;&amp;lt;/source&amp;gt;&amp;quot;,&lt;br /&gt;
		&amp;quot;selser [[4,0,2]]&amp;quot;: &amp;quot;g6ytvp&amp;lt;source lang=\&amp;quot;javascript\&amp;quot; inline&amp;gt;var a;&amp;lt;/source&amp;gt;10gwvyi.&amp;quot;,&lt;br /&gt;
		&amp;quot;selser [[3,0,2]]&amp;quot;: &amp;quot;&amp;lt;source lang=\&amp;quot;javascript\&amp;quot; inline&amp;gt;var a;&amp;lt;/source&amp;gt;kjtjv6.&amp;quot;,&lt;br /&gt;
		&amp;quot;selser [[3,0,4]]&amp;quot;: &amp;quot;&amp;lt;source lang=\&amp;quot;javascript\&amp;quot; inline&amp;gt;var a;&amp;lt;/source&amp;gt;zs6oqy&amp;quot;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jamesp1989</name></author>
	</entry>
	<entry>
		<id>https://necessewiki.com/mediawiki/index.php?title=User:Jamesp1989/common.css&amp;diff=24677</id>
		<title>User:Jamesp1989/common.css</title>
		<link rel="alternate" type="text/html" href="https://necessewiki.com/mediawiki/index.php?title=User:Jamesp1989/common.css&amp;diff=24677"/>
		<updated>2026-01-16T05:16:15Z</updated>

		<summary type="html">&lt;p&gt;Jamesp1989: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* Stylesheet generated by updateCSS.php */&lt;br /&gt;
pre { line-height: 125%; }&lt;br /&gt;
td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }&lt;br /&gt;
span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }&lt;br /&gt;
td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }&lt;br /&gt;
span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }&lt;br /&gt;
.mw-highlight .hll { background-color: #ffffcc }&lt;br /&gt;
.mw-highlight { background: #f8f8f8; }&lt;br /&gt;
.mw-highlight .c { color: #3D7B7B; font-style: italic } /* Comment */&lt;br /&gt;
.mw-highlight .err { border: 1px solid #FF0000 } /* Error */&lt;br /&gt;
.mw-highlight .k { color: #008000; font-weight: bold } /* Keyword */&lt;br /&gt;
.mw-highlight .o { color: #666666 } /* Operator */&lt;br /&gt;
.mw-highlight .ch { color: #3D7B7B; font-style: italic } /* Comment.Hashbang */&lt;br /&gt;
.mw-highlight .cm { color: #3D7B7B; font-style: italic } /* Comment.Multiline */&lt;br /&gt;
.mw-highlight .cp { color: #9C6500 } /* Comment.Preproc */&lt;br /&gt;
.mw-highlight .cpf { color: #3D7B7B; font-style: italic } /* Comment.PreprocFile */&lt;br /&gt;
.mw-highlight .c1 { color: #3D7B7B; font-style: italic } /* Comment.Single */&lt;br /&gt;
.mw-highlight .cs { color: #3D7B7B; font-style: italic } /* Comment.Special */&lt;br /&gt;
.mw-highlight .gd { color: #A00000 } /* Generic.Deleted */&lt;br /&gt;
.mw-highlight .ge { font-style: italic } /* Generic.Emph */&lt;br /&gt;
.mw-highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */&lt;br /&gt;
.mw-highlight .gr { color: #E40000 } /* Generic.Error */&lt;br /&gt;
.mw-highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */&lt;br /&gt;
.mw-highlight .gi { color: #008400 } /* Generic.Inserted */&lt;br /&gt;
.mw-highlight .go { color: #717171 } /* Generic.Output */&lt;br /&gt;
.mw-highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */&lt;br /&gt;
.mw-highlight .gs { font-weight: bold } /* Generic.Strong */&lt;br /&gt;
.mw-highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */&lt;br /&gt;
.mw-highlight .gt { color: #0044DD } /* Generic.Traceback */&lt;br /&gt;
.mw-highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */&lt;br /&gt;
.mw-highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */&lt;br /&gt;
.mw-highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */&lt;br /&gt;
.mw-highlight .kp { color: #008000 } /* Keyword.Pseudo */&lt;br /&gt;
.mw-highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */&lt;br /&gt;
.mw-highlight .kt { color: #B00040 } /* Keyword.Type */&lt;br /&gt;
.mw-highlight .m { color: #666666 } /* Literal.Number */&lt;br /&gt;
.mw-highlight .s { color: #BA2121 } /* Literal.String */&lt;br /&gt;
.mw-highlight .na { color: #687822 } /* Name.Attribute */&lt;br /&gt;
.mw-highlight .nb { color: #008000 } /* Name.Builtin */&lt;br /&gt;
.mw-highlight .nc { color: #0000FF; font-weight: bold } /* Name.Class */&lt;br /&gt;
.mw-highlight .no { color: #880000 } /* Name.Constant */&lt;br /&gt;
.mw-highlight .nd { color: #AA22FF } /* Name.Decorator */&lt;br /&gt;
.mw-highlight .ni { color: #717171; font-weight: bold } /* Name.Entity */&lt;br /&gt;
.mw-highlight .ne { color: #CB3F38; font-weight: bold } /* Name.Exception */&lt;br /&gt;
.mw-highlight .nf { color: #0000FF } /* Name.Function */&lt;br /&gt;
.mw-highlight .nl { color: #767600 } /* Name.Label */&lt;br /&gt;
.mw-highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */&lt;br /&gt;
.mw-highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */&lt;br /&gt;
.mw-highlight .nv { color: #19177C } /* Name.Variable */&lt;br /&gt;
.mw-highlight .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */&lt;br /&gt;
.mw-highlight .w { color: #bbbbbb } /* Text.Whitespace */&lt;br /&gt;
.mw-highlight .mb { color: #666666 } /* Literal.Number.Bin */&lt;br /&gt;
.mw-highlight .mf { color: #666666 } /* Literal.Number.Float */&lt;br /&gt;
.mw-highlight .mh { color: #666666 } /* Literal.Number.Hex */&lt;br /&gt;
.mw-highlight .mi { color: #666666 } /* Literal.Number.Integer */&lt;br /&gt;
.mw-highlight .mo { color: #666666 } /* Literal.Number.Oct */&lt;br /&gt;
.mw-highlight .sa { color: #BA2121 } /* Literal.String.Affix */&lt;br /&gt;
.mw-highlight .sb { color: #BA2121 } /* Literal.String.Backtick */&lt;br /&gt;
.mw-highlight .sc { color: #BA2121 } /* Literal.String.Char */&lt;br /&gt;
.mw-highlight .dl { color: #BA2121 } /* Literal.String.Delimiter */&lt;br /&gt;
.mw-highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */&lt;br /&gt;
.mw-highlight .s2 { color: #BA2121 } /* Literal.String.Double */&lt;br /&gt;
.mw-highlight .se { color: #AA5D1F; font-weight: bold } /* Literal.String.Escape */&lt;br /&gt;
.mw-highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */&lt;br /&gt;
.mw-highlight .si { color: #A45A77; font-weight: bold } /* Literal.String.Interpol */&lt;br /&gt;
.mw-highlight .sx { color: #008000 } /* Literal.String.Other */&lt;br /&gt;
.mw-highlight .sr { color: #A45A77 } /* Literal.String.Regex */&lt;br /&gt;
.mw-highlight .s1 { color: #BA2121 } /* Literal.String.Single */&lt;br /&gt;
.mw-highlight .ss { color: #19177C } /* Literal.String.Symbol */&lt;br /&gt;
.mw-highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */&lt;br /&gt;
.mw-highlight .fm { color: #0000FF } /* Name.Function.Magic */&lt;br /&gt;
.mw-highlight .vc { color: #19177C } /* Name.Variable.Class */&lt;br /&gt;
.mw-highlight .vg { color: #19177C } /* Name.Variable.Global */&lt;br /&gt;
.mw-highlight .vi { color: #19177C } /* Name.Variable.Instance */&lt;br /&gt;
.mw-highlight .vm { color: #19177C } /* Name.Variable.Magic */&lt;br /&gt;
.mw-highlight .il { color: #666666 } /* Literal.Number.Integer.Long */&lt;/div&gt;</summary>
		<author><name>Jamesp1989</name></author>
	</entry>
	<entry>
		<id>https://necessewiki.com/mediawiki/index.php?title=User:Jamesp1989/common.js&amp;diff=24676</id>
		<title>User:Jamesp1989/common.js</title>
		<link rel="alternate" type="text/html" href="https://necessewiki.com/mediawiki/index.php?title=User:Jamesp1989/common.js&amp;diff=24676"/>
		<updated>2026-01-16T05:09:05Z</updated>

		<summary type="html">&lt;p&gt;Jamesp1989: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* eslint-disable no-console */&lt;br /&gt;
(function () {&lt;br /&gt;
  &amp;quot;use strict&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  // --- Config (feel free to tweak) ---&lt;br /&gt;
  var HLJS_JS = &amp;quot;https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js&amp;quot;;&lt;br /&gt;
  var HLJS_CSS = &amp;quot;https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/github.min.css&amp;quot;;&lt;br /&gt;
  var ADD_COPY_BUTTON = true;&lt;br /&gt;
&lt;br /&gt;
  // --- Helpers ---&lt;br /&gt;
  function loadCss(url) {&lt;br /&gt;
    return new Promise(function (resolve, reject) {&lt;br /&gt;
      var link = document.createElement(&amp;quot;link&amp;quot;);&lt;br /&gt;
      link.rel = &amp;quot;stylesheet&amp;quot;;&lt;br /&gt;
      link.href = url;&lt;br /&gt;
      link.onload = resolve;&lt;br /&gt;
      link.onerror = reject;&lt;br /&gt;
      document.head.appendChild(link);&lt;br /&gt;
    });&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  function loadScript(url) {&lt;br /&gt;
    return new Promise(function (resolve, reject) {&lt;br /&gt;
      var s = document.createElement(&amp;quot;script&amp;quot;);&lt;br /&gt;
      s.src = url;&lt;br /&gt;
      s.async = true;&lt;br /&gt;
      s.onload = resolve;&lt;br /&gt;
      s.onerror = reject;&lt;br /&gt;
      document.head.appendChild(s);&lt;br /&gt;
    });&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  function getLangFromMwHighlight(pre) {&lt;br /&gt;
    // SyntaxHighlight output often includes classes like: mw-highlight-lang-php&lt;br /&gt;
    // We convert to highlight.js language names: language-php&lt;br /&gt;
    var m = (pre.className || &amp;quot;&amp;quot;).match(/\bmw-highlight-lang-([a-z0-9_+-]+)\b/i);&lt;br /&gt;
    return m ? m[1].toLowerCase() : &amp;quot;&amp;quot;;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  function hasTokenSpans(pre) {&lt;br /&gt;
    // If Pygments ran, it usually inserts lots of span elements for tokens.&lt;br /&gt;
    // If it failed, you often just get raw text with no spans.&lt;br /&gt;
    return !!pre.querySelector(&amp;quot;span&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  function ensureSyntaxHighlightCss() {&lt;br /&gt;
    // If SyntaxHighlight is installed, this module name is commonly available.&lt;br /&gt;
    // If it isn&#039;t, we silently ignore.&lt;br /&gt;
    if (window.mw &amp;amp;&amp;amp; mw.loader) {&lt;br /&gt;
      try {&lt;br /&gt;
        mw.loader.load(&amp;quot;ext.pygments&amp;quot;); // CSS/theme module from SyntaxHighlight extension&lt;br /&gt;
      } catch (e) {&lt;br /&gt;
        // ignore&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  function addCopyButtons(targetPres) {&lt;br /&gt;
    if (!navigator.clipboard) return;&lt;br /&gt;
&lt;br /&gt;
    targetPres.forEach(function (pre) {&lt;br /&gt;
      if (pre.dataset &amp;amp;&amp;amp; pre.dataset.hasCopyButton) return;&lt;br /&gt;
&lt;br /&gt;
      // Wrap in a positioned container&lt;br /&gt;
      var wrap = document.createElement(&amp;quot;div&amp;quot;);&lt;br /&gt;
      wrap.style.position = &amp;quot;relative&amp;quot;;&lt;br /&gt;
      wrap.className = &amp;quot;mw-userjs-codewrap&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
      pre.parentNode.insertBefore(wrap, pre);&lt;br /&gt;
      wrap.appendChild(pre);&lt;br /&gt;
&lt;br /&gt;
      var btn = document.createElement(&amp;quot;button&amp;quot;);&lt;br /&gt;
      btn.type = &amp;quot;button&amp;quot;;&lt;br /&gt;
      btn.textContent = &amp;quot;Copy&amp;quot;;&lt;br /&gt;
      btn.style.position = &amp;quot;absolute&amp;quot;;&lt;br /&gt;
      btn.style.top = &amp;quot;6px&amp;quot;;&lt;br /&gt;
      btn.style.right = &amp;quot;6px&amp;quot;;&lt;br /&gt;
      btn.style.padding = &amp;quot;4px 8px&amp;quot;;&lt;br /&gt;
      btn.style.fontSize = &amp;quot;12px&amp;quot;;&lt;br /&gt;
      btn.style.cursor = &amp;quot;pointer&amp;quot;;&lt;br /&gt;
      btn.style.opacity = &amp;quot;0.85&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
      btn.addEventListener(&amp;quot;click&amp;quot;, function () {&lt;br /&gt;
        navigator.clipboard.writeText(pre.innerText || pre.textContent || &amp;quot;&amp;quot;).then(function () {&lt;br /&gt;
          btn.textContent = &amp;quot;Copied!&amp;quot;;&lt;br /&gt;
          setTimeout(function () { btn.textContent = &amp;quot;Copy&amp;quot;; }, 1200);&lt;br /&gt;
        }).catch(function () {&lt;br /&gt;
          btn.textContent = &amp;quot;Failed&amp;quot;;&lt;br /&gt;
          setTimeout(function () { btn.textContent = &amp;quot;Copy&amp;quot;; }, 1200);&lt;br /&gt;
        });&lt;br /&gt;
      });&lt;br /&gt;
&lt;br /&gt;
      wrap.appendChild(btn);&lt;br /&gt;
      if (pre.dataset) pre.dataset.hasCopyButton = &amp;quot;1&amp;quot;;&lt;br /&gt;
    });&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  function runHighlightJsOnFailedBlocks() {&lt;br /&gt;
    var pres = Array.prototype.slice.call(document.querySelectorAll(&amp;quot;pre.mw-highlight&amp;quot;));&lt;br /&gt;
    // Only target blocks that look like SyntaxHighlight output but have no token spans.&lt;br /&gt;
    var needsClientHighlight = pres.filter(function (pre) {&lt;br /&gt;
      return !hasTokenSpans(pre);&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    if (!needsClientHighlight.length) {&lt;br /&gt;
      // Nothing to do.&lt;br /&gt;
      return;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return loadCss(HLJS_CSS)&lt;br /&gt;
      .then(function () { return loadScript(HLJS_JS); })&lt;br /&gt;
      .then(function () {&lt;br /&gt;
        if (!window.hljs) throw new Error(&amp;quot;highlight.js did not load&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        needsClientHighlight.forEach(function (pre) {&lt;br /&gt;
          // highlight.js expects a &amp;lt;code&amp;gt; element; if missing, add one.&lt;br /&gt;
          var code = pre.querySelector(&amp;quot;code&amp;quot;);&lt;br /&gt;
          if (!code) {&lt;br /&gt;
            code = document.createElement(&amp;quot;code&amp;quot;);&lt;br /&gt;
            // Preserve original text exactly.&lt;br /&gt;
            code.textContent = pre.textContent || &amp;quot;&amp;quot;;&lt;br /&gt;
            pre.textContent = &amp;quot;&amp;quot;;&lt;br /&gt;
            pre.appendChild(code);&lt;br /&gt;
          }&lt;br /&gt;
&lt;br /&gt;
          // Set language if we can infer it from mw-highlight-lang-*&lt;br /&gt;
          var lang = getLangFromMwHighlight(pre);&lt;br /&gt;
          if (lang) {&lt;br /&gt;
            code.classList.add(&amp;quot;language-&amp;quot; + lang);&lt;br /&gt;
          }&lt;br /&gt;
&lt;br /&gt;
          // Highlight&lt;br /&gt;
          try {&lt;br /&gt;
            window.hljs.highlightElement(code);&lt;br /&gt;
          } catch (e) {&lt;br /&gt;
            console.warn(&amp;quot;[UserJS] highlight.js failed for a block:&amp;quot;, e);&lt;br /&gt;
          }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        if (ADD_COPY_BUTTON) addCopyButtons(needsClientHighlight);&lt;br /&gt;
      })&lt;br /&gt;
      .catch(function (e) {&lt;br /&gt;
        console.warn(&amp;quot;[UserJS] highlight.js fallback could not load/run:&amp;quot;, e);&lt;br /&gt;
      });&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  function init() {&lt;br /&gt;
    ensureSyntaxHighlightCss();&lt;br /&gt;
&lt;br /&gt;
    // If SyntaxHighlight already worked and produced spans, CSS may still be missing.&lt;br /&gt;
    // Loading ext.pygments above usually solves that.&lt;br /&gt;
&lt;br /&gt;
    // If SyntaxHighlight failed (no spans), do client-side fallback.&lt;br /&gt;
    runHighlightJsOnFailedBlocks();&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Run after DOM is ready (MediaWiki-friendly)&lt;br /&gt;
  if (window.mw &amp;amp;&amp;amp; mw.hook) {&lt;br /&gt;
    mw.hook(&amp;quot;wikipage.content&amp;quot;).add(function () {&lt;br /&gt;
      init();&lt;br /&gt;
    });&lt;br /&gt;
  } else if (document.readyState === &amp;quot;loading&amp;quot;) {&lt;br /&gt;
    document.addEventListener(&amp;quot;DOMContentLoaded&amp;quot;, init);&lt;br /&gt;
  } else {&lt;br /&gt;
    init();&lt;br /&gt;
  }&lt;br /&gt;
})();&lt;/div&gt;</summary>
		<author><name>Jamesp1989</name></author>
	</entry>
	<entry>
		<id>https://necessewiki.com/mediawiki/index.php?title=User:Jamesp1989/common.js&amp;diff=24675</id>
		<title>User:Jamesp1989/common.js</title>
		<link rel="alternate" type="text/html" href="https://necessewiki.com/mediawiki/index.php?title=User:Jamesp1989/common.js&amp;diff=24675"/>
		<updated>2026-01-16T05:05:52Z</updated>

		<summary type="html">&lt;p&gt;Jamesp1989: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;w3CodeColor(document.getElementById(&amp;quot;myDiv&amp;quot;));&lt;br /&gt;
console.log(&amp;quot;My name is %s and I am %d years old.&amp;quot;, &amp;quot;Bob&amp;quot;, 30);&lt;br /&gt;
function w3CodeColor(elmnt, mode) {&lt;br /&gt;
  var lang = (mode || &amp;quot;html&amp;quot;);&lt;br /&gt;
  var elmntObj = (document.getElementById(elmnt) || elmnt);&lt;br /&gt;
  var elmntTxt = elmntObj.innerHTML;&lt;br /&gt;
  var tagcolor = &amp;quot;mediumblue&amp;quot;;&lt;br /&gt;
  var tagnamecolor = &amp;quot;brown&amp;quot;;&lt;br /&gt;
  var attributecolor = &amp;quot;red&amp;quot;;&lt;br /&gt;
  var attributevaluecolor = &amp;quot;mediumblue&amp;quot;;&lt;br /&gt;
  var commentcolor = &amp;quot;green&amp;quot;;&lt;br /&gt;
  var cssselectorcolor = &amp;quot;brown&amp;quot;;&lt;br /&gt;
  var csspropertycolor = &amp;quot;red&amp;quot;;&lt;br /&gt;
  var csspropertyvaluecolor = &amp;quot;mediumblue&amp;quot;;&lt;br /&gt;
  var cssdelimitercolor = &amp;quot;black&amp;quot;;&lt;br /&gt;
  var cssimportantcolor = &amp;quot;red&amp;quot;;  &lt;br /&gt;
  var jscolor = &amp;quot;black&amp;quot;;&lt;br /&gt;
  var jskeywordcolor = &amp;quot;mediumblue&amp;quot;;&lt;br /&gt;
  var jsstringcolor = &amp;quot;brown&amp;quot;;&lt;br /&gt;
  var jsnumbercolor = &amp;quot;red&amp;quot;;&lt;br /&gt;
  var jspropertycolor = &amp;quot;black&amp;quot;;&lt;br /&gt;
  elmntObj.style.fontFamily = &amp;quot;Consolas,&#039;Courier New&#039;, monospace&amp;quot;;&lt;br /&gt;
  if (!lang) {lang = &amp;quot;html&amp;quot;; }&lt;br /&gt;
  if (lang == &amp;quot;html&amp;quot;) {elmntTxt = htmlMode(elmntTxt);}&lt;br /&gt;
  if (lang == &amp;quot;css&amp;quot;) {elmntTxt = cssMode(elmntTxt);}&lt;br /&gt;
  if (lang == &amp;quot;js&amp;quot;) {elmntTxt = jsMode(elmntTxt);}&lt;br /&gt;
  elmntObj.innerHTML = elmntTxt;&lt;br /&gt;
&lt;br /&gt;
  function extract(str, start, end, func, repl) {&lt;br /&gt;
    var s, e, d = &amp;quot;&amp;quot;, a = [];&lt;br /&gt;
    while (str.search(start) &amp;gt; -1) {&lt;br /&gt;
      s = str.search(start);&lt;br /&gt;
      e = str.indexOf(end, s);&lt;br /&gt;
      if (e == -1) {e = str.length;}&lt;br /&gt;
      if (repl) {&lt;br /&gt;
        a.push(func(str.substring(s, e + (end.length))));      &lt;br /&gt;
        str = str.substring(0, s) + repl + str.substr(e + (end.length));&lt;br /&gt;
      } else {&lt;br /&gt;
        d += str.substring(0, s);&lt;br /&gt;
        d += func(str.substring(s, e + (end.length)));&lt;br /&gt;
        str = str.substr(e + (end.length));&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    this.rest = d + str;&lt;br /&gt;
    this.arr = a;&lt;br /&gt;
  }&lt;br /&gt;
  function htmlMode(txt) {&lt;br /&gt;
    var rest = txt, done = &amp;quot;&amp;quot;, php, comment, angular, startpos, endpos, note, i;&lt;br /&gt;
    comment = new extract(rest, &amp;quot;&amp;amp;lt;!--&amp;quot;, &amp;quot;--&amp;amp;gt;&amp;quot;, commentMode, &amp;quot;W3HTMLCOMMENTPOS&amp;quot;);&lt;br /&gt;
    rest = comment.rest;&lt;br /&gt;
    while (rest.indexOf(&amp;quot;&amp;amp;lt;&amp;quot;) &amp;gt; -1) {&lt;br /&gt;
      note = &amp;quot;&amp;quot;;&lt;br /&gt;
      startpos = rest.indexOf(&amp;quot;&amp;amp;lt;&amp;quot;);&lt;br /&gt;
      if (rest.substr(startpos, 9).toUpperCase() == &amp;quot;&amp;amp;LT;STYLE&amp;quot;) {note = &amp;quot;css&amp;quot;;}&lt;br /&gt;
      if (rest.substr(startpos, 10).toUpperCase() == &amp;quot;&amp;amp;LT;SCRIPT&amp;quot;) {note = &amp;quot;javascript&amp;quot;;}        &lt;br /&gt;
      endpos = rest.indexOf(&amp;quot;&amp;amp;gt;&amp;quot;, startpos);&lt;br /&gt;
      if (endpos == -1) {endpos = rest.length;}&lt;br /&gt;
      done += rest.substring(0, startpos);&lt;br /&gt;
      done += tagMode(rest.substring(startpos, endpos + 4));&lt;br /&gt;
      rest = rest.substr(endpos + 4);&lt;br /&gt;
      if (note == &amp;quot;css&amp;quot;) {&lt;br /&gt;
        endpos = rest.indexOf(&amp;quot;&amp;amp;lt;/style&amp;amp;gt;&amp;quot;);&lt;br /&gt;
        if (endpos &amp;gt; -1) {&lt;br /&gt;
          done += cssMode(rest.substring(0, endpos));&lt;br /&gt;
          rest = rest.substr(endpos);&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
      if (note == &amp;quot;javascript&amp;quot;) {&lt;br /&gt;
        endpos = rest.indexOf(&amp;quot;&amp;amp;lt;/script&amp;amp;gt;&amp;quot;);&lt;br /&gt;
        if (endpos &amp;gt; -1) {&lt;br /&gt;
          done += jsMode(rest.substring(0, endpos));&lt;br /&gt;
          rest = rest.substr(endpos);&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    rest = done + rest;&lt;br /&gt;
    for (i = 0; i &amp;lt; comment.arr.length; i++) {&lt;br /&gt;
        rest = rest.replace(&amp;quot;W3HTMLCOMMENTPOS&amp;quot;, comment.arr[i]);&lt;br /&gt;
    }&lt;br /&gt;
    return rest;&lt;br /&gt;
  }&lt;br /&gt;
  function tagMode(txt) {&lt;br /&gt;
    var rest = txt, done = &amp;quot;&amp;quot;, startpos, endpos, result;&lt;br /&gt;
    while (rest.search(/(\s|&amp;lt;br&amp;gt;)/) &amp;gt; -1) {    &lt;br /&gt;
      startpos = rest.search(/(\s|&amp;lt;br&amp;gt;)/);&lt;br /&gt;
      endpos = rest.indexOf(&amp;quot;&amp;amp;gt;&amp;quot;);&lt;br /&gt;
      if (endpos == -1) {endpos = rest.length;}&lt;br /&gt;
      done += rest.substring(0, startpos);&lt;br /&gt;
      done += attributeMode(rest.substring(startpos, endpos));&lt;br /&gt;
      rest = rest.substr(endpos);&lt;br /&gt;
    }&lt;br /&gt;
    result = done + rest;&lt;br /&gt;
    result = &amp;quot;&amp;lt;span style=color:&amp;quot; + tagcolor + &amp;quot;&amp;gt;&amp;amp;lt;&amp;lt;/span&amp;gt;&amp;quot; + result.substring(4);&lt;br /&gt;
    if (result.substr(result.length - 4, 4) == &amp;quot;&amp;amp;gt;&amp;quot;) {&lt;br /&gt;
      result = result.substring(0, result.length - 4) + &amp;quot;&amp;lt;span style=color:&amp;quot; + tagcolor + &amp;quot;&amp;gt;&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    return &amp;quot;&amp;lt;span style=color:&amp;quot; + tagnamecolor + &amp;quot;&amp;gt;&amp;quot; + result + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;;&lt;br /&gt;
  }&lt;br /&gt;
  function attributeMode(txt) {&lt;br /&gt;
    var rest = txt, done = &amp;quot;&amp;quot;, startpos, endpos, singlefnuttpos, doublefnuttpos, spacepos;&lt;br /&gt;
    while (rest.indexOf(&amp;quot;=&amp;quot;) &amp;gt; -1) {&lt;br /&gt;
      endpos = -1;&lt;br /&gt;
      startpos = rest.indexOf(&amp;quot;=&amp;quot;);&lt;br /&gt;
      singlefnuttpos = rest.indexOf(&amp;quot;&#039;&amp;quot;, startpos);&lt;br /&gt;
      doublefnuttpos = rest.indexOf(&#039;&amp;quot;&#039;, startpos);&lt;br /&gt;
      spacepos = rest.indexOf(&amp;quot; &amp;quot;, startpos + 2);&lt;br /&gt;
      if (spacepos &amp;gt; -1 &amp;amp;&amp;amp; (spacepos &amp;lt; singlefnuttpos || singlefnuttpos == -1) &amp;amp;&amp;amp; (spacepos &amp;lt; doublefnuttpos || doublefnuttpos == -1)) {&lt;br /&gt;
        endpos = rest.indexOf(&amp;quot; &amp;quot;, startpos);      &lt;br /&gt;
      } else if (doublefnuttpos &amp;gt; -1 &amp;amp;&amp;amp; (doublefnuttpos &amp;lt; singlefnuttpos || singlefnuttpos == -1) &amp;amp;&amp;amp; (doublefnuttpos &amp;lt; spacepos || spacepos == -1)) {&lt;br /&gt;
        endpos = rest.indexOf(&#039;&amp;quot;&#039;, rest.indexOf(&#039;&amp;quot;&#039;, startpos) + 1);&lt;br /&gt;
      } else if (singlefnuttpos &amp;gt; -1 &amp;amp;&amp;amp; (singlefnuttpos &amp;lt; doublefnuttpos || doublefnuttpos == -1) &amp;amp;&amp;amp; (singlefnuttpos &amp;lt; spacepos || spacepos == -1)) {&lt;br /&gt;
        endpos = rest.indexOf(&amp;quot;&#039;&amp;quot;, rest.indexOf(&amp;quot;&#039;&amp;quot;, startpos) + 1);&lt;br /&gt;
      }&lt;br /&gt;
      if (!endpos || endpos == -1 || endpos &amp;lt; startpos) {endpos = rest.length;}&lt;br /&gt;
      done += rest.substring(0, startpos);&lt;br /&gt;
      done += attributeValueMode(rest.substring(startpos, endpos + 1));&lt;br /&gt;
      rest = rest.substr(endpos + 1);&lt;br /&gt;
    }&lt;br /&gt;
    return &amp;quot;&amp;lt;span style=color:&amp;quot; + attributecolor + &amp;quot;&amp;gt;&amp;quot; + done + rest + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;;&lt;br /&gt;
  }&lt;br /&gt;
  function attributeValueMode(txt) {&lt;br /&gt;
    return &amp;quot;&amp;lt;span style=color:&amp;quot; + attributevaluecolor + &amp;quot;&amp;gt;&amp;quot; + txt + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;;&lt;br /&gt;
  }&lt;br /&gt;
  function commentMode(txt) {&lt;br /&gt;
    return &amp;quot;&amp;lt;span style=color:&amp;quot; + commentcolor + &amp;quot;&amp;gt;&amp;quot; + txt + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;;&lt;br /&gt;
  }&lt;br /&gt;
  function cssMode(txt) {&lt;br /&gt;
    var rest = txt, done = &amp;quot;&amp;quot;, s, e, comment, i, midz, c, cc;&lt;br /&gt;
    comment = new extract(rest, /\/\*/, &amp;quot;*/&amp;quot;, commentMode, &amp;quot;W3CSSCOMMENTPOS&amp;quot;);&lt;br /&gt;
    rest = comment.rest;&lt;br /&gt;
    while (rest.search(&amp;quot;{&amp;quot;) &amp;gt; -1) {&lt;br /&gt;
      s = rest.search(&amp;quot;{&amp;quot;);&lt;br /&gt;
      midz = rest.substr(s + 1);&lt;br /&gt;
      cc = 1;&lt;br /&gt;
      c = 0;&lt;br /&gt;
      for (i = 0; i &amp;lt; midz.length; i++) {&lt;br /&gt;
        if (midz.substr(i, 1) == &amp;quot;{&amp;quot;) {cc++; c++}&lt;br /&gt;
        if (midz.substr(i, 1) == &amp;quot;}&amp;quot;) {cc--;}&lt;br /&gt;
        if (cc == 0) {break;}&lt;br /&gt;
      }&lt;br /&gt;
      if (cc != 0) {c = 0;}&lt;br /&gt;
      e = s;&lt;br /&gt;
      for (i = 0; i &amp;lt;= c; i++) {&lt;br /&gt;
        e = rest.indexOf(&amp;quot;}&amp;quot;, e + 1);&lt;br /&gt;
      }&lt;br /&gt;
      if (e == -1) {e = rest.length;}&lt;br /&gt;
      done += rest.substring(0, s + 1);&lt;br /&gt;
      done += cssPropertyMode(rest.substring(s + 1, e));&lt;br /&gt;
      rest = rest.substr(e);&lt;br /&gt;
    }&lt;br /&gt;
    rest = done + rest;&lt;br /&gt;
    rest = rest.replace(/{/g, &amp;quot;&amp;lt;span style=color:&amp;quot; + cssdelimitercolor + &amp;quot;&amp;gt;{&amp;lt;/span&amp;gt;&amp;quot;);&lt;br /&gt;
    rest = rest.replace(/}/g, &amp;quot;&amp;lt;span style=color:&amp;quot; + cssdelimitercolor + &amp;quot;&amp;gt;}&amp;lt;/span&amp;gt;&amp;quot;);&lt;br /&gt;
    for (i = 0; i &amp;lt; comment.arr.length; i++) {&lt;br /&gt;
        rest = rest.replace(&amp;quot;W3CSSCOMMENTPOS&amp;quot;, comment.arr[i]);&lt;br /&gt;
    }&lt;br /&gt;
    return &amp;quot;&amp;lt;span style=color:&amp;quot; + cssselectorcolor + &amp;quot;&amp;gt;&amp;quot; + rest + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;;&lt;br /&gt;
  }&lt;br /&gt;
  function cssPropertyMode(txt) {&lt;br /&gt;
    var rest = txt, done = &amp;quot;&amp;quot;, s, e, n, loop;&lt;br /&gt;
    if (rest.indexOf(&amp;quot;{&amp;quot;) &amp;gt; -1 ) { return cssMode(rest); }&lt;br /&gt;
    while (rest.search(&amp;quot;:&amp;quot;) &amp;gt; -1) {&lt;br /&gt;
      s = rest.search(&amp;quot;:&amp;quot;);&lt;br /&gt;
      loop = true;&lt;br /&gt;
      n = s;&lt;br /&gt;
      while (loop == true) {&lt;br /&gt;
        loop = false;&lt;br /&gt;
        e = rest.indexOf(&amp;quot;;&amp;quot;, n);&lt;br /&gt;
        if (rest.substring(e - 5, e + 1) == &amp;quot;&amp;amp;nbsp;&amp;quot;) {&lt;br /&gt;
          loop = true;&lt;br /&gt;
          n = e + 1;&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
      if (e == -1) {e = rest.length;}&lt;br /&gt;
      done += rest.substring(0, s);&lt;br /&gt;
      done += cssPropertyValueMode(rest.substring(s, e + 1));&lt;br /&gt;
      rest = rest.substr(e + 1);&lt;br /&gt;
    }&lt;br /&gt;
    return &amp;quot;&amp;lt;span style=color:&amp;quot; + csspropertycolor + &amp;quot;&amp;gt;&amp;quot; + done + rest + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;;&lt;br /&gt;
  }&lt;br /&gt;
  function cssPropertyValueMode(txt) {&lt;br /&gt;
    var rest = txt, done = &amp;quot;&amp;quot;, s;&lt;br /&gt;
    rest = &amp;quot;&amp;lt;span style=color:&amp;quot; + cssdelimitercolor + &amp;quot;&amp;gt;:&amp;lt;/span&amp;gt;&amp;quot; + rest.substring(1);&lt;br /&gt;
    while (rest.search(/!important/i) &amp;gt; -1) {&lt;br /&gt;
      s = rest.search(/!important/i);&lt;br /&gt;
      done += rest.substring(0, s);&lt;br /&gt;
      done += cssImportantMode(rest.substring(s, s + 10));&lt;br /&gt;
      rest = rest.substr(s + 10);&lt;br /&gt;
    }&lt;br /&gt;
    result = done + rest;    &lt;br /&gt;
    if (result.substr(result.length - 1, 1) == &amp;quot;;&amp;quot; &amp;amp;&amp;amp; result.substr(result.length - 6, 6) != &amp;quot;&amp;amp;nbsp;&amp;quot; &amp;amp;&amp;amp; result.substr(result.length - 4, 4) != &amp;quot;&amp;amp;lt;&amp;quot; &amp;amp;&amp;amp; result.substr(result.length - 4, 4) != &amp;quot;&amp;amp;gt;&amp;quot; &amp;amp;&amp;amp; result.substr(result.length - 5, 5) != &amp;quot;&amp;amp;amp;&amp;quot;) {&lt;br /&gt;
      result = result.substring(0, result.length - 1) + &amp;quot;&amp;lt;span style=color:&amp;quot; + cssdelimitercolor + &amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    return &amp;quot;&amp;lt;span style=color:&amp;quot; + csspropertyvaluecolor + &amp;quot;&amp;gt;&amp;quot; + result + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;;&lt;br /&gt;
  }&lt;br /&gt;
  function cssImportantMode(txt) {&lt;br /&gt;
    return &amp;quot;&amp;lt;span style=color:&amp;quot; + cssimportantcolor + &amp;quot;;font-weight:bold;&amp;gt;&amp;quot; + txt + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;;&lt;br /&gt;
  }&lt;br /&gt;
  function jsMode(txt) {&lt;br /&gt;
    var rest = txt, done = &amp;quot;&amp;quot;, esc = [], i, cc, tt = &amp;quot;&amp;quot;, sfnuttpos, dfnuttpos, compos, comlinepos, keywordpos, numpos, mypos, dotpos, y;&lt;br /&gt;
    for (i = 0; i &amp;lt; rest.length; i++)  {&lt;br /&gt;
      cc = rest.substr(i, 1);&lt;br /&gt;
      if (cc == &amp;quot;\\&amp;quot;) {&lt;br /&gt;
        esc.push(rest.substr(i, 2));&lt;br /&gt;
        cc = &amp;quot;W3JSESCAPE&amp;quot;;&lt;br /&gt;
        i++;&lt;br /&gt;
      }&lt;br /&gt;
      tt += cc;&lt;br /&gt;
    }&lt;br /&gt;
    rest = tt;&lt;br /&gt;
    y = 1;&lt;br /&gt;
    while (y == 1) {&lt;br /&gt;
      sfnuttpos = getPos(rest, &amp;quot;&#039;&amp;quot;, &amp;quot;&#039;&amp;quot;, jsStringMode);&lt;br /&gt;
      dfnuttpos = getPos(rest, &#039;&amp;quot;&#039;, &#039;&amp;quot;&#039;, jsStringMode);&lt;br /&gt;
      compos = getPos(rest, /\/\*/, &amp;quot;*/&amp;quot;, commentMode);&lt;br /&gt;
      comlinepos = getPos(rest, /\/\//, &amp;quot;&amp;lt;br&amp;gt;&amp;quot;, commentMode);      &lt;br /&gt;
      numpos = getNumPos(rest, jsNumberMode);&lt;br /&gt;
      keywordpos = getKeywordPos(&amp;quot;js&amp;quot;, rest, jsKeywordMode);&lt;br /&gt;
      dotpos = getDotPos(rest, jsPropertyMode);&lt;br /&gt;
      if (Math.max(numpos[0], sfnuttpos[0], dfnuttpos[0], compos[0], comlinepos[0], keywordpos[0], dotpos[0]) == -1) {break;}&lt;br /&gt;
      mypos = getMinPos(numpos, sfnuttpos, dfnuttpos, compos, comlinepos, keywordpos, dotpos);&lt;br /&gt;
      if (mypos[0] == -1) {break;}&lt;br /&gt;
      if (mypos[0] &amp;gt; -1) {&lt;br /&gt;
        done += rest.substring(0, mypos[0]);&lt;br /&gt;
        done += mypos[2](rest.substring(mypos[0], mypos[1]));&lt;br /&gt;
        rest = rest.substr(mypos[1]);&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    rest = done + rest;&lt;br /&gt;
    for (i = 0; i &amp;lt; esc.length; i++) {&lt;br /&gt;
      rest = rest.replace(&amp;quot;W3JSESCAPE&amp;quot;, esc[i]);&lt;br /&gt;
    }&lt;br /&gt;
    return &amp;quot;&amp;lt;span style=color:&amp;quot; + jscolor + &amp;quot;&amp;gt;&amp;quot; + rest + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;;&lt;br /&gt;
  }&lt;br /&gt;
  function jsStringMode(txt) {&lt;br /&gt;
    return &amp;quot;&amp;lt;span style=color:&amp;quot; + jsstringcolor + &amp;quot;&amp;gt;&amp;quot; + txt + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;;&lt;br /&gt;
  }&lt;br /&gt;
  function jsKeywordMode(txt) {&lt;br /&gt;
    return &amp;quot;&amp;lt;span style=color:&amp;quot; + jskeywordcolor + &amp;quot;&amp;gt;&amp;quot; + txt + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;;&lt;br /&gt;
  }&lt;br /&gt;
  function jsNumberMode(txt) {&lt;br /&gt;
    return &amp;quot;&amp;lt;span style=color:&amp;quot; + jsnumbercolor + &amp;quot;&amp;gt;&amp;quot; + txt + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;;&lt;br /&gt;
  }&lt;br /&gt;
  function jsPropertyMode(txt) {&lt;br /&gt;
    return &amp;quot;&amp;lt;span style=color:&amp;quot; + jspropertycolor + &amp;quot;&amp;gt;&amp;quot; + txt + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;;&lt;br /&gt;
  }&lt;br /&gt;
  function getDotPos(txt, func) {&lt;br /&gt;
    var x, i, j, s, e, arr = [&amp;quot;.&amp;quot;,&amp;quot;&amp;lt;&amp;quot;, &amp;quot; &amp;quot;, &amp;quot;;&amp;quot;, &amp;quot;(&amp;quot;, &amp;quot;+&amp;quot;, &amp;quot;)&amp;quot;, &amp;quot;[&amp;quot;, &amp;quot;]&amp;quot;, &amp;quot;,&amp;quot;, &amp;quot;&amp;amp;&amp;quot;, &amp;quot;:&amp;quot;, &amp;quot;{&amp;quot;, &amp;quot;}&amp;quot;, &amp;quot;/&amp;quot; ,&amp;quot;-&amp;quot;, &amp;quot;*&amp;quot;, &amp;quot;|&amp;quot;, &amp;quot;%&amp;quot;];&lt;br /&gt;
    s = txt.indexOf(&amp;quot;.&amp;quot;);&lt;br /&gt;
    if (s &amp;gt; -1) {&lt;br /&gt;
      x = txt.substr(s + 1);&lt;br /&gt;
      for (j = 0; j &amp;lt; x.length; j++) {&lt;br /&gt;
        cc = x[j];&lt;br /&gt;
        for (i = 0; i &amp;lt; arr.length; i++) {&lt;br /&gt;
          if (cc.indexOf(arr[i]) &amp;gt; -1) {&lt;br /&gt;
            e = j;&lt;br /&gt;
            return [s + 1, e + s + 1, func];&lt;br /&gt;
          }&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    return [-1, -1, func];&lt;br /&gt;
  }&lt;br /&gt;
  function getMinPos() {&lt;br /&gt;
    var i, arr = [];&lt;br /&gt;
    for (i = 0; i &amp;lt; arguments.length; i++) {&lt;br /&gt;
      if (arguments[i][0] &amp;gt; -1) {&lt;br /&gt;
        if (arr.length == 0 || arguments[i][0] &amp;lt; arr[0]) {arr = arguments[i];}&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    if (arr.length == 0) {arr = arguments[i];}&lt;br /&gt;
    return arr;&lt;br /&gt;
  }&lt;br /&gt;
  function getKeywordPos(typ, txt, func) {&lt;br /&gt;
    var words, i, pos, rpos = -1, rpos2 = -1, patt;&lt;br /&gt;
    if (typ == &amp;quot;js&amp;quot;) {&lt;br /&gt;
      words = [&amp;quot;abstract&amp;quot;,&amp;quot;arguments&amp;quot;,&amp;quot;boolean&amp;quot;,&amp;quot;break&amp;quot;,&amp;quot;byte&amp;quot;,&amp;quot;case&amp;quot;,&amp;quot;catch&amp;quot;,&amp;quot;char&amp;quot;,&amp;quot;class&amp;quot;,&amp;quot;const&amp;quot;,&amp;quot;continue&amp;quot;,&amp;quot;debugger&amp;quot;,&amp;quot;default&amp;quot;,&amp;quot;delete&amp;quot;,&lt;br /&gt;
      &amp;quot;do&amp;quot;,&amp;quot;double&amp;quot;,&amp;quot;else&amp;quot;,&amp;quot;enum&amp;quot;,&amp;quot;eval&amp;quot;,&amp;quot;export&amp;quot;,&amp;quot;extends&amp;quot;,&amp;quot;false&amp;quot;,&amp;quot;final&amp;quot;,&amp;quot;finally&amp;quot;,&amp;quot;float&amp;quot;,&amp;quot;for&amp;quot;,&amp;quot;function&amp;quot;,&amp;quot;goto&amp;quot;,&amp;quot;if&amp;quot;,&amp;quot;implements&amp;quot;,&amp;quot;import&amp;quot;,&lt;br /&gt;
      &amp;quot;in&amp;quot;,&amp;quot;instanceof&amp;quot;,&amp;quot;int&amp;quot;,&amp;quot;interface&amp;quot;,&amp;quot;let&amp;quot;,&amp;quot;long&amp;quot;,&amp;quot;NaN&amp;quot;,&amp;quot;native&amp;quot;,&amp;quot;new&amp;quot;,&amp;quot;null&amp;quot;,&amp;quot;package&amp;quot;,&amp;quot;private&amp;quot;,&amp;quot;protected&amp;quot;,&amp;quot;public&amp;quot;,&amp;quot;return&amp;quot;,&amp;quot;short&amp;quot;,&amp;quot;static&amp;quot;,&lt;br /&gt;
      &amp;quot;super&amp;quot;,&amp;quot;switch&amp;quot;,&amp;quot;synchronized&amp;quot;,&amp;quot;this&amp;quot;,&amp;quot;throw&amp;quot;,&amp;quot;throws&amp;quot;,&amp;quot;transient&amp;quot;,&amp;quot;true&amp;quot;,&amp;quot;try&amp;quot;,&amp;quot;typeof&amp;quot;,&amp;quot;var&amp;quot;,&amp;quot;void&amp;quot;,&amp;quot;volatile&amp;quot;,&amp;quot;while&amp;quot;,&amp;quot;with&amp;quot;,&amp;quot;yield&amp;quot;];&lt;br /&gt;
    }&lt;br /&gt;
    for (i = 0; i &amp;lt; words.length; i++) {&lt;br /&gt;
      pos = txt.indexOf(words[i]);&lt;br /&gt;
      if (pos &amp;gt; -1) {&lt;br /&gt;
        patt = /\W/g;&lt;br /&gt;
        if (txt.substr(pos + words[i].length,1).match(patt) &amp;amp;&amp;amp; txt.substr(pos - 1,1).match(patt)) {&lt;br /&gt;
          if (pos &amp;gt; -1 &amp;amp;&amp;amp; (rpos == -1 || pos &amp;lt; rpos)) {&lt;br /&gt;
            rpos = pos;&lt;br /&gt;
            rpos2 = rpos + words[i].length;&lt;br /&gt;
          }&lt;br /&gt;
        }&lt;br /&gt;
      } &lt;br /&gt;
    }&lt;br /&gt;
    return [rpos, rpos2, func];&lt;br /&gt;
  }&lt;br /&gt;
  function getPos(txt, start, end, func) {&lt;br /&gt;
    var s, e;&lt;br /&gt;
    s = txt.search(start);&lt;br /&gt;
    e = txt.indexOf(end, s + (end.length));&lt;br /&gt;
    if (e == -1) {e = txt.length;}&lt;br /&gt;
    return [s, e + (end.length), func];&lt;br /&gt;
  }&lt;br /&gt;
  function getNumPos(txt, func) {&lt;br /&gt;
    var arr = [&amp;quot;&amp;lt;br&amp;gt;&amp;quot;, &amp;quot; &amp;quot;, &amp;quot;;&amp;quot;, &amp;quot;(&amp;quot;, &amp;quot;+&amp;quot;, &amp;quot;)&amp;quot;, &amp;quot;[&amp;quot;, &amp;quot;]&amp;quot;, &amp;quot;,&amp;quot;, &amp;quot;&amp;amp;&amp;quot;, &amp;quot;:&amp;quot;, &amp;quot;{&amp;quot;, &amp;quot;}&amp;quot;, &amp;quot;/&amp;quot; ,&amp;quot;-&amp;quot;, &amp;quot;*&amp;quot;, &amp;quot;|&amp;quot;, &amp;quot;%&amp;quot;, &amp;quot;=&amp;quot;], i, j, c, startpos = 0, endpos, word;&lt;br /&gt;
    for (i = 0; i &amp;lt; txt.length; i++) {&lt;br /&gt;
      for (j = 0; j &amp;lt; arr.length; j++) {&lt;br /&gt;
        c = txt.substr(i, arr[j].length);&lt;br /&gt;
        if (c == arr[j]) {&lt;br /&gt;
          if (c == &amp;quot;-&amp;quot; &amp;amp;&amp;amp; (txt.substr(i - 1, 1) == &amp;quot;e&amp;quot; || txt.substr(i - 1, 1) == &amp;quot;E&amp;quot;)) {&lt;br /&gt;
            continue;&lt;br /&gt;
          }&lt;br /&gt;
          endpos = i;&lt;br /&gt;
          if (startpos &amp;lt; endpos) {&lt;br /&gt;
            word = txt.substring(startpos, endpos);&lt;br /&gt;
            if (!isNaN(word)) {return [startpos, endpos, func];}&lt;br /&gt;
          }&lt;br /&gt;
          i += arr[j].length;&lt;br /&gt;
          startpos = i;&lt;br /&gt;
          i -= 1;&lt;br /&gt;
          break;&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }  &lt;br /&gt;
    return [-1, -1, func];&lt;br /&gt;
  }  &lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>Jamesp1989</name></author>
	</entry>
	<entry>
		<id>https://necessewiki.com/mediawiki/index.php?title=User:Jamesp1989/common.css&amp;diff=24674</id>
		<title>User:Jamesp1989/common.css</title>
		<link rel="alternate" type="text/html" href="https://necessewiki.com/mediawiki/index.php?title=User:Jamesp1989/common.css&amp;diff=24674"/>
		<updated>2026-01-16T05:02:55Z</updated>

		<summary type="html">&lt;p&gt;Jamesp1989: Created blank page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Jamesp1989</name></author>
	</entry>
	<entry>
		<id>https://necessewiki.com/mediawiki/index.php?title=User:Jamesp1989&amp;diff=24673</id>
		<title>User:Jamesp1989</title>
		<link rel="alternate" type="text/html" href="https://necessewiki.com/mediawiki/index.php?title=User:Jamesp1989&amp;diff=24673"/>
		<updated>2026-01-16T05:02:21Z</updated>

		<summary type="html">&lt;p&gt;Jamesp1989: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div id=&amp;quot;myDiv&amp;quot;&amp;gt;&lt;br /&gt;
&amp;amp;lt;!DOCTYPE html&amp;amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;lt;html&amp;amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;lt;body&amp;amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;lt;h1&amp;amp;gt;Testing an HTML Syntax Highlighter&amp;amp;lt;/h2&amp;amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;lt;p&amp;amp;gt;Hello world!&amp;amp;lt;/p&amp;amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;lt;a href=&amp;quot;https://www.w3schools.com&amp;quot;&amp;amp;gt;Back to School&amp;amp;lt;/a&amp;amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;lt;/body&amp;amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;amp;lt;/html&amp;amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jamesp1989</name></author>
	</entry>
	<entry>
		<id>https://necessewiki.com/mediawiki/index.php?title=User:Jamesp1989/common.js&amp;diff=24672</id>
		<title>User:Jamesp1989/common.js</title>
		<link rel="alternate" type="text/html" href="https://necessewiki.com/mediawiki/index.php?title=User:Jamesp1989/common.js&amp;diff=24672"/>
		<updated>2026-01-16T05:01:35Z</updated>

		<summary type="html">&lt;p&gt;Jamesp1989: Created page with &amp;quot;w3CodeColor(document.getElementById(&amp;quot;myDiv&amp;quot;));  function w3CodeColor(elmnt, mode) {   var lang = (mode || &amp;quot;html&amp;quot;);   var elmntObj = (document.getElementById(elmnt) || elmnt);   var elmntTxt = elmntObj.innerHTML;   var tagcolor = &amp;quot;mediumblue&amp;quot;;   var tagnamecolor = &amp;quot;brown&amp;quot;;   var attributecolor = &amp;quot;red&amp;quot;;   var attributevaluecolor = &amp;quot;mediumblue&amp;quot;;   var commentcolor = &amp;quot;green&amp;quot;;   var cssselectorcolor = &amp;quot;brown&amp;quot;;   var csspropertycolor = &amp;quot;red&amp;quot;;   var csspropertyvaluecolor = &amp;quot;med...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;w3CodeColor(document.getElementById(&amp;quot;myDiv&amp;quot;));&lt;br /&gt;
&lt;br /&gt;
function w3CodeColor(elmnt, mode) {&lt;br /&gt;
  var lang = (mode || &amp;quot;html&amp;quot;);&lt;br /&gt;
  var elmntObj = (document.getElementById(elmnt) || elmnt);&lt;br /&gt;
  var elmntTxt = elmntObj.innerHTML;&lt;br /&gt;
  var tagcolor = &amp;quot;mediumblue&amp;quot;;&lt;br /&gt;
  var tagnamecolor = &amp;quot;brown&amp;quot;;&lt;br /&gt;
  var attributecolor = &amp;quot;red&amp;quot;;&lt;br /&gt;
  var attributevaluecolor = &amp;quot;mediumblue&amp;quot;;&lt;br /&gt;
  var commentcolor = &amp;quot;green&amp;quot;;&lt;br /&gt;
  var cssselectorcolor = &amp;quot;brown&amp;quot;;&lt;br /&gt;
  var csspropertycolor = &amp;quot;red&amp;quot;;&lt;br /&gt;
  var csspropertyvaluecolor = &amp;quot;mediumblue&amp;quot;;&lt;br /&gt;
  var cssdelimitercolor = &amp;quot;black&amp;quot;;&lt;br /&gt;
  var cssimportantcolor = &amp;quot;red&amp;quot;;  &lt;br /&gt;
  var jscolor = &amp;quot;black&amp;quot;;&lt;br /&gt;
  var jskeywordcolor = &amp;quot;mediumblue&amp;quot;;&lt;br /&gt;
  var jsstringcolor = &amp;quot;brown&amp;quot;;&lt;br /&gt;
  var jsnumbercolor = &amp;quot;red&amp;quot;;&lt;br /&gt;
  var jspropertycolor = &amp;quot;black&amp;quot;;&lt;br /&gt;
  elmntObj.style.fontFamily = &amp;quot;Consolas,&#039;Courier New&#039;, monospace&amp;quot;;&lt;br /&gt;
  if (!lang) {lang = &amp;quot;html&amp;quot;; }&lt;br /&gt;
  if (lang == &amp;quot;html&amp;quot;) {elmntTxt = htmlMode(elmntTxt);}&lt;br /&gt;
  if (lang == &amp;quot;css&amp;quot;) {elmntTxt = cssMode(elmntTxt);}&lt;br /&gt;
  if (lang == &amp;quot;js&amp;quot;) {elmntTxt = jsMode(elmntTxt);}&lt;br /&gt;
  elmntObj.innerHTML = elmntTxt;&lt;br /&gt;
&lt;br /&gt;
  function extract(str, start, end, func, repl) {&lt;br /&gt;
    var s, e, d = &amp;quot;&amp;quot;, a = [];&lt;br /&gt;
    while (str.search(start) &amp;gt; -1) {&lt;br /&gt;
      s = str.search(start);&lt;br /&gt;
      e = str.indexOf(end, s);&lt;br /&gt;
      if (e == -1) {e = str.length;}&lt;br /&gt;
      if (repl) {&lt;br /&gt;
        a.push(func(str.substring(s, e + (end.length))));      &lt;br /&gt;
        str = str.substring(0, s) + repl + str.substr(e + (end.length));&lt;br /&gt;
      } else {&lt;br /&gt;
        d += str.substring(0, s);&lt;br /&gt;
        d += func(str.substring(s, e + (end.length)));&lt;br /&gt;
        str = str.substr(e + (end.length));&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    this.rest = d + str;&lt;br /&gt;
    this.arr = a;&lt;br /&gt;
  }&lt;br /&gt;
  function htmlMode(txt) {&lt;br /&gt;
    var rest = txt, done = &amp;quot;&amp;quot;, php, comment, angular, startpos, endpos, note, i;&lt;br /&gt;
    comment = new extract(rest, &amp;quot;&amp;amp;lt;!--&amp;quot;, &amp;quot;--&amp;amp;gt;&amp;quot;, commentMode, &amp;quot;W3HTMLCOMMENTPOS&amp;quot;);&lt;br /&gt;
    rest = comment.rest;&lt;br /&gt;
    while (rest.indexOf(&amp;quot;&amp;amp;lt;&amp;quot;) &amp;gt; -1) {&lt;br /&gt;
      note = &amp;quot;&amp;quot;;&lt;br /&gt;
      startpos = rest.indexOf(&amp;quot;&amp;amp;lt;&amp;quot;);&lt;br /&gt;
      if (rest.substr(startpos, 9).toUpperCase() == &amp;quot;&amp;amp;LT;STYLE&amp;quot;) {note = &amp;quot;css&amp;quot;;}&lt;br /&gt;
      if (rest.substr(startpos, 10).toUpperCase() == &amp;quot;&amp;amp;LT;SCRIPT&amp;quot;) {note = &amp;quot;javascript&amp;quot;;}        &lt;br /&gt;
      endpos = rest.indexOf(&amp;quot;&amp;amp;gt;&amp;quot;, startpos);&lt;br /&gt;
      if (endpos == -1) {endpos = rest.length;}&lt;br /&gt;
      done += rest.substring(0, startpos);&lt;br /&gt;
      done += tagMode(rest.substring(startpos, endpos + 4));&lt;br /&gt;
      rest = rest.substr(endpos + 4);&lt;br /&gt;
      if (note == &amp;quot;css&amp;quot;) {&lt;br /&gt;
        endpos = rest.indexOf(&amp;quot;&amp;amp;lt;/style&amp;amp;gt;&amp;quot;);&lt;br /&gt;
        if (endpos &amp;gt; -1) {&lt;br /&gt;
          done += cssMode(rest.substring(0, endpos));&lt;br /&gt;
          rest = rest.substr(endpos);&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
      if (note == &amp;quot;javascript&amp;quot;) {&lt;br /&gt;
        endpos = rest.indexOf(&amp;quot;&amp;amp;lt;/script&amp;amp;gt;&amp;quot;);&lt;br /&gt;
        if (endpos &amp;gt; -1) {&lt;br /&gt;
          done += jsMode(rest.substring(0, endpos));&lt;br /&gt;
          rest = rest.substr(endpos);&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    rest = done + rest;&lt;br /&gt;
    for (i = 0; i &amp;lt; comment.arr.length; i++) {&lt;br /&gt;
        rest = rest.replace(&amp;quot;W3HTMLCOMMENTPOS&amp;quot;, comment.arr[i]);&lt;br /&gt;
    }&lt;br /&gt;
    return rest;&lt;br /&gt;
  }&lt;br /&gt;
  function tagMode(txt) {&lt;br /&gt;
    var rest = txt, done = &amp;quot;&amp;quot;, startpos, endpos, result;&lt;br /&gt;
    while (rest.search(/(\s|&amp;lt;br&amp;gt;)/) &amp;gt; -1) {    &lt;br /&gt;
      startpos = rest.search(/(\s|&amp;lt;br&amp;gt;)/);&lt;br /&gt;
      endpos = rest.indexOf(&amp;quot;&amp;amp;gt;&amp;quot;);&lt;br /&gt;
      if (endpos == -1) {endpos = rest.length;}&lt;br /&gt;
      done += rest.substring(0, startpos);&lt;br /&gt;
      done += attributeMode(rest.substring(startpos, endpos));&lt;br /&gt;
      rest = rest.substr(endpos);&lt;br /&gt;
    }&lt;br /&gt;
    result = done + rest;&lt;br /&gt;
    result = &amp;quot;&amp;lt;span style=color:&amp;quot; + tagcolor + &amp;quot;&amp;gt;&amp;amp;lt;&amp;lt;/span&amp;gt;&amp;quot; + result.substring(4);&lt;br /&gt;
    if (result.substr(result.length - 4, 4) == &amp;quot;&amp;amp;gt;&amp;quot;) {&lt;br /&gt;
      result = result.substring(0, result.length - 4) + &amp;quot;&amp;lt;span style=color:&amp;quot; + tagcolor + &amp;quot;&amp;gt;&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    return &amp;quot;&amp;lt;span style=color:&amp;quot; + tagnamecolor + &amp;quot;&amp;gt;&amp;quot; + result + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;;&lt;br /&gt;
  }&lt;br /&gt;
  function attributeMode(txt) {&lt;br /&gt;
    var rest = txt, done = &amp;quot;&amp;quot;, startpos, endpos, singlefnuttpos, doublefnuttpos, spacepos;&lt;br /&gt;
    while (rest.indexOf(&amp;quot;=&amp;quot;) &amp;gt; -1) {&lt;br /&gt;
      endpos = -1;&lt;br /&gt;
      startpos = rest.indexOf(&amp;quot;=&amp;quot;);&lt;br /&gt;
      singlefnuttpos = rest.indexOf(&amp;quot;&#039;&amp;quot;, startpos);&lt;br /&gt;
      doublefnuttpos = rest.indexOf(&#039;&amp;quot;&#039;, startpos);&lt;br /&gt;
      spacepos = rest.indexOf(&amp;quot; &amp;quot;, startpos + 2);&lt;br /&gt;
      if (spacepos &amp;gt; -1 &amp;amp;&amp;amp; (spacepos &amp;lt; singlefnuttpos || singlefnuttpos == -1) &amp;amp;&amp;amp; (spacepos &amp;lt; doublefnuttpos || doublefnuttpos == -1)) {&lt;br /&gt;
        endpos = rest.indexOf(&amp;quot; &amp;quot;, startpos);      &lt;br /&gt;
      } else if (doublefnuttpos &amp;gt; -1 &amp;amp;&amp;amp; (doublefnuttpos &amp;lt; singlefnuttpos || singlefnuttpos == -1) &amp;amp;&amp;amp; (doublefnuttpos &amp;lt; spacepos || spacepos == -1)) {&lt;br /&gt;
        endpos = rest.indexOf(&#039;&amp;quot;&#039;, rest.indexOf(&#039;&amp;quot;&#039;, startpos) + 1);&lt;br /&gt;
      } else if (singlefnuttpos &amp;gt; -1 &amp;amp;&amp;amp; (singlefnuttpos &amp;lt; doublefnuttpos || doublefnuttpos == -1) &amp;amp;&amp;amp; (singlefnuttpos &amp;lt; spacepos || spacepos == -1)) {&lt;br /&gt;
        endpos = rest.indexOf(&amp;quot;&#039;&amp;quot;, rest.indexOf(&amp;quot;&#039;&amp;quot;, startpos) + 1);&lt;br /&gt;
      }&lt;br /&gt;
      if (!endpos || endpos == -1 || endpos &amp;lt; startpos) {endpos = rest.length;}&lt;br /&gt;
      done += rest.substring(0, startpos);&lt;br /&gt;
      done += attributeValueMode(rest.substring(startpos, endpos + 1));&lt;br /&gt;
      rest = rest.substr(endpos + 1);&lt;br /&gt;
    }&lt;br /&gt;
    return &amp;quot;&amp;lt;span style=color:&amp;quot; + attributecolor + &amp;quot;&amp;gt;&amp;quot; + done + rest + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;;&lt;br /&gt;
  }&lt;br /&gt;
  function attributeValueMode(txt) {&lt;br /&gt;
    return &amp;quot;&amp;lt;span style=color:&amp;quot; + attributevaluecolor + &amp;quot;&amp;gt;&amp;quot; + txt + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;;&lt;br /&gt;
  }&lt;br /&gt;
  function commentMode(txt) {&lt;br /&gt;
    return &amp;quot;&amp;lt;span style=color:&amp;quot; + commentcolor + &amp;quot;&amp;gt;&amp;quot; + txt + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;;&lt;br /&gt;
  }&lt;br /&gt;
  function cssMode(txt) {&lt;br /&gt;
    var rest = txt, done = &amp;quot;&amp;quot;, s, e, comment, i, midz, c, cc;&lt;br /&gt;
    comment = new extract(rest, /\/\*/, &amp;quot;*/&amp;quot;, commentMode, &amp;quot;W3CSSCOMMENTPOS&amp;quot;);&lt;br /&gt;
    rest = comment.rest;&lt;br /&gt;
    while (rest.search(&amp;quot;{&amp;quot;) &amp;gt; -1) {&lt;br /&gt;
      s = rest.search(&amp;quot;{&amp;quot;);&lt;br /&gt;
      midz = rest.substr(s + 1);&lt;br /&gt;
      cc = 1;&lt;br /&gt;
      c = 0;&lt;br /&gt;
      for (i = 0; i &amp;lt; midz.length; i++) {&lt;br /&gt;
        if (midz.substr(i, 1) == &amp;quot;{&amp;quot;) {cc++; c++}&lt;br /&gt;
        if (midz.substr(i, 1) == &amp;quot;}&amp;quot;) {cc--;}&lt;br /&gt;
        if (cc == 0) {break;}&lt;br /&gt;
      }&lt;br /&gt;
      if (cc != 0) {c = 0;}&lt;br /&gt;
      e = s;&lt;br /&gt;
      for (i = 0; i &amp;lt;= c; i++) {&lt;br /&gt;
        e = rest.indexOf(&amp;quot;}&amp;quot;, e + 1);&lt;br /&gt;
      }&lt;br /&gt;
      if (e == -1) {e = rest.length;}&lt;br /&gt;
      done += rest.substring(0, s + 1);&lt;br /&gt;
      done += cssPropertyMode(rest.substring(s + 1, e));&lt;br /&gt;
      rest = rest.substr(e);&lt;br /&gt;
    }&lt;br /&gt;
    rest = done + rest;&lt;br /&gt;
    rest = rest.replace(/{/g, &amp;quot;&amp;lt;span style=color:&amp;quot; + cssdelimitercolor + &amp;quot;&amp;gt;{&amp;lt;/span&amp;gt;&amp;quot;);&lt;br /&gt;
    rest = rest.replace(/}/g, &amp;quot;&amp;lt;span style=color:&amp;quot; + cssdelimitercolor + &amp;quot;&amp;gt;}&amp;lt;/span&amp;gt;&amp;quot;);&lt;br /&gt;
    for (i = 0; i &amp;lt; comment.arr.length; i++) {&lt;br /&gt;
        rest = rest.replace(&amp;quot;W3CSSCOMMENTPOS&amp;quot;, comment.arr[i]);&lt;br /&gt;
    }&lt;br /&gt;
    return &amp;quot;&amp;lt;span style=color:&amp;quot; + cssselectorcolor + &amp;quot;&amp;gt;&amp;quot; + rest + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;;&lt;br /&gt;
  }&lt;br /&gt;
  function cssPropertyMode(txt) {&lt;br /&gt;
    var rest = txt, done = &amp;quot;&amp;quot;, s, e, n, loop;&lt;br /&gt;
    if (rest.indexOf(&amp;quot;{&amp;quot;) &amp;gt; -1 ) { return cssMode(rest); }&lt;br /&gt;
    while (rest.search(&amp;quot;:&amp;quot;) &amp;gt; -1) {&lt;br /&gt;
      s = rest.search(&amp;quot;:&amp;quot;);&lt;br /&gt;
      loop = true;&lt;br /&gt;
      n = s;&lt;br /&gt;
      while (loop == true) {&lt;br /&gt;
        loop = false;&lt;br /&gt;
        e = rest.indexOf(&amp;quot;;&amp;quot;, n);&lt;br /&gt;
        if (rest.substring(e - 5, e + 1) == &amp;quot;&amp;amp;nbsp;&amp;quot;) {&lt;br /&gt;
          loop = true;&lt;br /&gt;
          n = e + 1;&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
      if (e == -1) {e = rest.length;}&lt;br /&gt;
      done += rest.substring(0, s);&lt;br /&gt;
      done += cssPropertyValueMode(rest.substring(s, e + 1));&lt;br /&gt;
      rest = rest.substr(e + 1);&lt;br /&gt;
    }&lt;br /&gt;
    return &amp;quot;&amp;lt;span style=color:&amp;quot; + csspropertycolor + &amp;quot;&amp;gt;&amp;quot; + done + rest + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;;&lt;br /&gt;
  }&lt;br /&gt;
  function cssPropertyValueMode(txt) {&lt;br /&gt;
    var rest = txt, done = &amp;quot;&amp;quot;, s;&lt;br /&gt;
    rest = &amp;quot;&amp;lt;span style=color:&amp;quot; + cssdelimitercolor + &amp;quot;&amp;gt;:&amp;lt;/span&amp;gt;&amp;quot; + rest.substring(1);&lt;br /&gt;
    while (rest.search(/!important/i) &amp;gt; -1) {&lt;br /&gt;
      s = rest.search(/!important/i);&lt;br /&gt;
      done += rest.substring(0, s);&lt;br /&gt;
      done += cssImportantMode(rest.substring(s, s + 10));&lt;br /&gt;
      rest = rest.substr(s + 10);&lt;br /&gt;
    }&lt;br /&gt;
    result = done + rest;    &lt;br /&gt;
    if (result.substr(result.length - 1, 1) == &amp;quot;;&amp;quot; &amp;amp;&amp;amp; result.substr(result.length - 6, 6) != &amp;quot;&amp;amp;nbsp;&amp;quot; &amp;amp;&amp;amp; result.substr(result.length - 4, 4) != &amp;quot;&amp;amp;lt;&amp;quot; &amp;amp;&amp;amp; result.substr(result.length - 4, 4) != &amp;quot;&amp;amp;gt;&amp;quot; &amp;amp;&amp;amp; result.substr(result.length - 5, 5) != &amp;quot;&amp;amp;amp;&amp;quot;) {&lt;br /&gt;
      result = result.substring(0, result.length - 1) + &amp;quot;&amp;lt;span style=color:&amp;quot; + cssdelimitercolor + &amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    return &amp;quot;&amp;lt;span style=color:&amp;quot; + csspropertyvaluecolor + &amp;quot;&amp;gt;&amp;quot; + result + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;;&lt;br /&gt;
  }&lt;br /&gt;
  function cssImportantMode(txt) {&lt;br /&gt;
    return &amp;quot;&amp;lt;span style=color:&amp;quot; + cssimportantcolor + &amp;quot;;font-weight:bold;&amp;gt;&amp;quot; + txt + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;;&lt;br /&gt;
  }&lt;br /&gt;
  function jsMode(txt) {&lt;br /&gt;
    var rest = txt, done = &amp;quot;&amp;quot;, esc = [], i, cc, tt = &amp;quot;&amp;quot;, sfnuttpos, dfnuttpos, compos, comlinepos, keywordpos, numpos, mypos, dotpos, y;&lt;br /&gt;
    for (i = 0; i &amp;lt; rest.length; i++)  {&lt;br /&gt;
      cc = rest.substr(i, 1);&lt;br /&gt;
      if (cc == &amp;quot;\\&amp;quot;) {&lt;br /&gt;
        esc.push(rest.substr(i, 2));&lt;br /&gt;
        cc = &amp;quot;W3JSESCAPE&amp;quot;;&lt;br /&gt;
        i++;&lt;br /&gt;
      }&lt;br /&gt;
      tt += cc;&lt;br /&gt;
    }&lt;br /&gt;
    rest = tt;&lt;br /&gt;
    y = 1;&lt;br /&gt;
    while (y == 1) {&lt;br /&gt;
      sfnuttpos = getPos(rest, &amp;quot;&#039;&amp;quot;, &amp;quot;&#039;&amp;quot;, jsStringMode);&lt;br /&gt;
      dfnuttpos = getPos(rest, &#039;&amp;quot;&#039;, &#039;&amp;quot;&#039;, jsStringMode);&lt;br /&gt;
      compos = getPos(rest, /\/\*/, &amp;quot;*/&amp;quot;, commentMode);&lt;br /&gt;
      comlinepos = getPos(rest, /\/\//, &amp;quot;&amp;lt;br&amp;gt;&amp;quot;, commentMode);      &lt;br /&gt;
      numpos = getNumPos(rest, jsNumberMode);&lt;br /&gt;
      keywordpos = getKeywordPos(&amp;quot;js&amp;quot;, rest, jsKeywordMode);&lt;br /&gt;
      dotpos = getDotPos(rest, jsPropertyMode);&lt;br /&gt;
      if (Math.max(numpos[0], sfnuttpos[0], dfnuttpos[0], compos[0], comlinepos[0], keywordpos[0], dotpos[0]) == -1) {break;}&lt;br /&gt;
      mypos = getMinPos(numpos, sfnuttpos, dfnuttpos, compos, comlinepos, keywordpos, dotpos);&lt;br /&gt;
      if (mypos[0] == -1) {break;}&lt;br /&gt;
      if (mypos[0] &amp;gt; -1) {&lt;br /&gt;
        done += rest.substring(0, mypos[0]);&lt;br /&gt;
        done += mypos[2](rest.substring(mypos[0], mypos[1]));&lt;br /&gt;
        rest = rest.substr(mypos[1]);&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    rest = done + rest;&lt;br /&gt;
    for (i = 0; i &amp;lt; esc.length; i++) {&lt;br /&gt;
      rest = rest.replace(&amp;quot;W3JSESCAPE&amp;quot;, esc[i]);&lt;br /&gt;
    }&lt;br /&gt;
    return &amp;quot;&amp;lt;span style=color:&amp;quot; + jscolor + &amp;quot;&amp;gt;&amp;quot; + rest + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;;&lt;br /&gt;
  }&lt;br /&gt;
  function jsStringMode(txt) {&lt;br /&gt;
    return &amp;quot;&amp;lt;span style=color:&amp;quot; + jsstringcolor + &amp;quot;&amp;gt;&amp;quot; + txt + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;;&lt;br /&gt;
  }&lt;br /&gt;
  function jsKeywordMode(txt) {&lt;br /&gt;
    return &amp;quot;&amp;lt;span style=color:&amp;quot; + jskeywordcolor + &amp;quot;&amp;gt;&amp;quot; + txt + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;;&lt;br /&gt;
  }&lt;br /&gt;
  function jsNumberMode(txt) {&lt;br /&gt;
    return &amp;quot;&amp;lt;span style=color:&amp;quot; + jsnumbercolor + &amp;quot;&amp;gt;&amp;quot; + txt + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;;&lt;br /&gt;
  }&lt;br /&gt;
  function jsPropertyMode(txt) {&lt;br /&gt;
    return &amp;quot;&amp;lt;span style=color:&amp;quot; + jspropertycolor + &amp;quot;&amp;gt;&amp;quot; + txt + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;;&lt;br /&gt;
  }&lt;br /&gt;
  function getDotPos(txt, func) {&lt;br /&gt;
    var x, i, j, s, e, arr = [&amp;quot;.&amp;quot;,&amp;quot;&amp;lt;&amp;quot;, &amp;quot; &amp;quot;, &amp;quot;;&amp;quot;, &amp;quot;(&amp;quot;, &amp;quot;+&amp;quot;, &amp;quot;)&amp;quot;, &amp;quot;[&amp;quot;, &amp;quot;]&amp;quot;, &amp;quot;,&amp;quot;, &amp;quot;&amp;amp;&amp;quot;, &amp;quot;:&amp;quot;, &amp;quot;{&amp;quot;, &amp;quot;}&amp;quot;, &amp;quot;/&amp;quot; ,&amp;quot;-&amp;quot;, &amp;quot;*&amp;quot;, &amp;quot;|&amp;quot;, &amp;quot;%&amp;quot;];&lt;br /&gt;
    s = txt.indexOf(&amp;quot;.&amp;quot;);&lt;br /&gt;
    if (s &amp;gt; -1) {&lt;br /&gt;
      x = txt.substr(s + 1);&lt;br /&gt;
      for (j = 0; j &amp;lt; x.length; j++) {&lt;br /&gt;
        cc = x[j];&lt;br /&gt;
        for (i = 0; i &amp;lt; arr.length; i++) {&lt;br /&gt;
          if (cc.indexOf(arr[i]) &amp;gt; -1) {&lt;br /&gt;
            e = j;&lt;br /&gt;
            return [s + 1, e + s + 1, func];&lt;br /&gt;
          }&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    return [-1, -1, func];&lt;br /&gt;
  }&lt;br /&gt;
  function getMinPos() {&lt;br /&gt;
    var i, arr = [];&lt;br /&gt;
    for (i = 0; i &amp;lt; arguments.length; i++) {&lt;br /&gt;
      if (arguments[i][0] &amp;gt; -1) {&lt;br /&gt;
        if (arr.length == 0 || arguments[i][0] &amp;lt; arr[0]) {arr = arguments[i];}&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    if (arr.length == 0) {arr = arguments[i];}&lt;br /&gt;
    return arr;&lt;br /&gt;
  }&lt;br /&gt;
  function getKeywordPos(typ, txt, func) {&lt;br /&gt;
    var words, i, pos, rpos = -1, rpos2 = -1, patt;&lt;br /&gt;
    if (typ == &amp;quot;js&amp;quot;) {&lt;br /&gt;
      words = [&amp;quot;abstract&amp;quot;,&amp;quot;arguments&amp;quot;,&amp;quot;boolean&amp;quot;,&amp;quot;break&amp;quot;,&amp;quot;byte&amp;quot;,&amp;quot;case&amp;quot;,&amp;quot;catch&amp;quot;,&amp;quot;char&amp;quot;,&amp;quot;class&amp;quot;,&amp;quot;const&amp;quot;,&amp;quot;continue&amp;quot;,&amp;quot;debugger&amp;quot;,&amp;quot;default&amp;quot;,&amp;quot;delete&amp;quot;,&lt;br /&gt;
      &amp;quot;do&amp;quot;,&amp;quot;double&amp;quot;,&amp;quot;else&amp;quot;,&amp;quot;enum&amp;quot;,&amp;quot;eval&amp;quot;,&amp;quot;export&amp;quot;,&amp;quot;extends&amp;quot;,&amp;quot;false&amp;quot;,&amp;quot;final&amp;quot;,&amp;quot;finally&amp;quot;,&amp;quot;float&amp;quot;,&amp;quot;for&amp;quot;,&amp;quot;function&amp;quot;,&amp;quot;goto&amp;quot;,&amp;quot;if&amp;quot;,&amp;quot;implements&amp;quot;,&amp;quot;import&amp;quot;,&lt;br /&gt;
      &amp;quot;in&amp;quot;,&amp;quot;instanceof&amp;quot;,&amp;quot;int&amp;quot;,&amp;quot;interface&amp;quot;,&amp;quot;let&amp;quot;,&amp;quot;long&amp;quot;,&amp;quot;NaN&amp;quot;,&amp;quot;native&amp;quot;,&amp;quot;new&amp;quot;,&amp;quot;null&amp;quot;,&amp;quot;package&amp;quot;,&amp;quot;private&amp;quot;,&amp;quot;protected&amp;quot;,&amp;quot;public&amp;quot;,&amp;quot;return&amp;quot;,&amp;quot;short&amp;quot;,&amp;quot;static&amp;quot;,&lt;br /&gt;
      &amp;quot;super&amp;quot;,&amp;quot;switch&amp;quot;,&amp;quot;synchronized&amp;quot;,&amp;quot;this&amp;quot;,&amp;quot;throw&amp;quot;,&amp;quot;throws&amp;quot;,&amp;quot;transient&amp;quot;,&amp;quot;true&amp;quot;,&amp;quot;try&amp;quot;,&amp;quot;typeof&amp;quot;,&amp;quot;var&amp;quot;,&amp;quot;void&amp;quot;,&amp;quot;volatile&amp;quot;,&amp;quot;while&amp;quot;,&amp;quot;with&amp;quot;,&amp;quot;yield&amp;quot;];&lt;br /&gt;
    }&lt;br /&gt;
    for (i = 0; i &amp;lt; words.length; i++) {&lt;br /&gt;
      pos = txt.indexOf(words[i]);&lt;br /&gt;
      if (pos &amp;gt; -1) {&lt;br /&gt;
        patt = /\W/g;&lt;br /&gt;
        if (txt.substr(pos + words[i].length,1).match(patt) &amp;amp;&amp;amp; txt.substr(pos - 1,1).match(patt)) {&lt;br /&gt;
          if (pos &amp;gt; -1 &amp;amp;&amp;amp; (rpos == -1 || pos &amp;lt; rpos)) {&lt;br /&gt;
            rpos = pos;&lt;br /&gt;
            rpos2 = rpos + words[i].length;&lt;br /&gt;
          }&lt;br /&gt;
        }&lt;br /&gt;
      } &lt;br /&gt;
    }&lt;br /&gt;
    return [rpos, rpos2, func];&lt;br /&gt;
  }&lt;br /&gt;
  function getPos(txt, start, end, func) {&lt;br /&gt;
    var s, e;&lt;br /&gt;
    s = txt.search(start);&lt;br /&gt;
    e = txt.indexOf(end, s + (end.length));&lt;br /&gt;
    if (e == -1) {e = txt.length;}&lt;br /&gt;
    return [s, e + (end.length), func];&lt;br /&gt;
  }&lt;br /&gt;
  function getNumPos(txt, func) {&lt;br /&gt;
    var arr = [&amp;quot;&amp;lt;br&amp;gt;&amp;quot;, &amp;quot; &amp;quot;, &amp;quot;;&amp;quot;, &amp;quot;(&amp;quot;, &amp;quot;+&amp;quot;, &amp;quot;)&amp;quot;, &amp;quot;[&amp;quot;, &amp;quot;]&amp;quot;, &amp;quot;,&amp;quot;, &amp;quot;&amp;amp;&amp;quot;, &amp;quot;:&amp;quot;, &amp;quot;{&amp;quot;, &amp;quot;}&amp;quot;, &amp;quot;/&amp;quot; ,&amp;quot;-&amp;quot;, &amp;quot;*&amp;quot;, &amp;quot;|&amp;quot;, &amp;quot;%&amp;quot;, &amp;quot;=&amp;quot;], i, j, c, startpos = 0, endpos, word;&lt;br /&gt;
    for (i = 0; i &amp;lt; txt.length; i++) {&lt;br /&gt;
      for (j = 0; j &amp;lt; arr.length; j++) {&lt;br /&gt;
        c = txt.substr(i, arr[j].length);&lt;br /&gt;
        if (c == arr[j]) {&lt;br /&gt;
          if (c == &amp;quot;-&amp;quot; &amp;amp;&amp;amp; (txt.substr(i - 1, 1) == &amp;quot;e&amp;quot; || txt.substr(i - 1, 1) == &amp;quot;E&amp;quot;)) {&lt;br /&gt;
            continue;&lt;br /&gt;
          }&lt;br /&gt;
          endpos = i;&lt;br /&gt;
          if (startpos &amp;lt; endpos) {&lt;br /&gt;
            word = txt.substring(startpos, endpos);&lt;br /&gt;
            if (!isNaN(word)) {return [startpos, endpos, func];}&lt;br /&gt;
          }&lt;br /&gt;
          i += arr[j].length;&lt;br /&gt;
          startpos = i;&lt;br /&gt;
          i -= 1;&lt;br /&gt;
          break;&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }  &lt;br /&gt;
    return [-1, -1, func];&lt;br /&gt;
  }  &lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>Jamesp1989</name></author>
	</entry>
	<entry>
		<id>https://necessewiki.com/mediawiki/index.php?title=Modding/draft&amp;diff=24671</id>
		<title>Modding/draft</title>
		<link rel="alternate" type="text/html" href="https://necessewiki.com/mediawiki/index.php?title=Modding/draft&amp;diff=24671"/>
		<updated>2026-01-16T04:44:34Z</updated>

		<summary type="html">&lt;p&gt;Jamesp1989: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;syntaxhighlight lang=&amp;quot;CSS&amp;quot;&amp;gt;&lt;br /&gt;
/* CSS placed here will be applied to all non-mobile skins */&lt;br /&gt;
/* For mobile site, edit MediaWiki:Mobile.css */&lt;br /&gt;
&lt;br /&gt;
html body {&lt;br /&gt;
  background: url(&amp;quot;https://necessewiki.com/mediawiki/images/background.png&amp;quot;) no-repeat fixed center bottom / cover #e6e6e6;&lt;br /&gt;
  height: auto !important;&lt;br /&gt;
  margin-top: 0 !important;&lt;br /&gt;
  min-height: 100%;&lt;br /&gt;
  display: flex;&lt;br /&gt;
  flex-direction: column;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@font-face {&lt;br /&gt;
  font-family: &#039;Necessebit&#039;;&lt;br /&gt;
  src: url(https://necessewiki.com/mediawiki/resources/assets/necessebit.ttf) format(&#039;truetype&#039;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
h1, h2 {&lt;br /&gt;
  border-bottom: 1px solid #83643a !important;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
img {&lt;br /&gt;
  max-width: 100%;&lt;br /&gt;
  height: auto;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.mw-body {&lt;br /&gt;
  border: 2px solid #100700;&lt;br /&gt;
  box-shadow: inset #ffb21f 0 0 0 2px, inset #d0812a 0 0 0 4px, inset #2e2018 0 0 0 6px, inset #8e6b54 0 0 0 8px, 0px 0px 10px #000;&lt;br /&gt;
  margin-right: 1em;&lt;br /&gt;
  background-color: #bd9e75;&lt;br /&gt;
  background-image: url(&amp;quot;/mediawiki/images/formbackground.png&amp;quot;);&lt;br /&gt;
  border-right-width: 2px;&lt;br /&gt;
  color: #000;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.mw-footer {&lt;br /&gt;
  text-shadow: 0 0 10px #000, 0 0 10px #000, 0 0 10px #000, 0 0 10px #000;&lt;br /&gt;
  font-weight: bold;&lt;br /&gt;
  color: #ccc;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.mw-footer a {&lt;br /&gt;
  color: #1d8df0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.mw-footer li {&lt;br /&gt;
  color: inherit !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Mobile stuff */&lt;br /&gt;
#mw-mf-viewport #mw-mf-page-center {&lt;br /&gt;
  background: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-mf-viewport .mw-body {&lt;br /&gt;
  margin-right: 0.5em;&lt;br /&gt;
  margin-left: 0.5em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-mf-viewport .last-modified-bar, #mw-mf-viewport .last-modified-bar a, #mw-mf-viewport .last-modified-bar a:visited, #mw-mf-viewport .last-modified-bar .last-modified-text-accent {&lt;br /&gt;
  color: #ccc;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-mf-viewport .last-modified-bar .minerva-icon {&lt;br /&gt;
  background-color: #ccc;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-mf-viewport .last-modified-bar {&lt;br /&gt;
  background: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-mf-viewport .last-modified-bar__text {&lt;br /&gt;
  overflow: initial;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-mf-viewport .mw-footer &amp;gt; .post-content {&lt;br /&gt;
  overflow: initial&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.page-actions-menu__list-item .cdx-button {&lt;br /&gt;
  color: #222 !important;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.header-container.header-chrome {&lt;br /&gt;
  background: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.catlinks {&lt;br /&gt;
  background: #e9dcc1;&lt;br /&gt;
  border: 1px solid #a38d5e;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.necesse-title-image {&lt;br /&gt;
  width: 100%;&lt;br /&gt;
  max-width: 640px;&lt;br /&gt;
  height: auto;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.necesse-content-cell {&lt;br /&gt;
  border: 2px solid #191b22;&lt;br /&gt;
  box-shadow: inset #dbc498 0 0 0 2px, 0px 0px 6px #000;&lt;br /&gt;
  background: #e9dcc1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.necesse-header {&lt;br /&gt;
  font-family: &#039;Necessebit&#039;;&lt;br /&gt;
  font-size: 24px;&lt;br /&gt;
  font-weight: bold;&lt;br /&gt;
  color: #111;&lt;br /&gt;
  text-shadow: 0px 2px 1px #919191;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.necesse-main-menu-game {&lt;br /&gt;
  min-width: 300px;&lt;br /&gt;
}&lt;br /&gt;
.necesse-main-menu-world {&lt;br /&gt;
  min-width: 300px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media only screen and (min-width: 1000px) {&lt;br /&gt;
  .necesse-main-menu-game {&lt;br /&gt;
    min-width: 600px;&lt;br /&gt;
  }&lt;br /&gt;
  .necesse-main-menu-world {&lt;br /&gt;
    min-width: 650px;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.itemplate {&lt;br /&gt;
  margin: 1px 5px 1px 2px;&lt;br /&gt;
  display: block;&lt;br /&gt;
  white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.necesse-infobox {&lt;br /&gt;
  box-shadow: inset #dbc498 0 0 0 2px, 0px 0px 6px #000;&lt;br /&gt;
  border: 2px solid #191b22;&lt;br /&gt;
  background: #e9dcc1;&lt;br /&gt;
  float: right;&lt;br /&gt;
  margin-left: 15px;&lt;br /&gt;
  margin-bottom: 15px;&lt;br /&gt;
  min-width: 300px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.content .infobox {&lt;br /&gt;
  box-shadow: inset #dbc498 0 0 0 2px, 0px 0px 6px #000;&lt;br /&gt;
  border: 2px solid #191b22;&lt;br /&gt;
  background: #e9dcc1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.infobox {&lt;br /&gt;
  float: right;&lt;br /&gt;
  width: 300px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.content .infobox th, .content .infobox td {&lt;br /&gt;
  border-bottom: 1px solid #a38d5e;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.infobox-table {&lt;br /&gt;
  width: 100%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.infobox-header {&lt;br /&gt;
  text-align: center;&lt;br /&gt;
  font-size: 20px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.infobox-region {&lt;br /&gt;
  background-color: #ee922c;&lt;br /&gt;
  border-radius: 5px;&lt;br /&gt;
  font-weight: bold;&lt;br /&gt;
  text-align: center;&lt;br /&gt;
  color: #222;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.infobox-section {&lt;br /&gt;
  padding-left: 10px;&lt;br /&gt;
  color: black;&lt;br /&gt;
  white-space: nowrap;&lt;br /&gt;
  vertical-align: top;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.infobox-detail {&lt;br /&gt;
  padding-right: 10px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.wikitable {&lt;br /&gt;
  border-collapse: separate;&lt;br /&gt;
  border: none;&lt;br /&gt;
  background-color: initial;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.wikitable.rounded {&lt;br /&gt;
  border: 1px solid rgba(0, 0, 0, 0.5);&lt;br /&gt;
  border-radius: 5px;&lt;br /&gt;
  padding: 0.1em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.wikitable tr th {&lt;br /&gt;
  background: #ee922c;&lt;br /&gt;
  padding: 0.2em 0.4em;&lt;br /&gt;
  text-align: center;&lt;br /&gt;
  font-weight: bold;&lt;br /&gt;
  font-size: 16px;&lt;br /&gt;
  color: #222;&lt;br /&gt;
  border: 1px solid #ab7e4c;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.wikitable tr th a {&lt;br /&gt;
  color: #99d;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.wikitable tr th a.new {&lt;br /&gt;
  color: #ba0000;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.wikitable tr td {&lt;br /&gt;
  background: #e9dcc1;&lt;br /&gt;
  padding: 0.2em 0.4em;&lt;br /&gt;
  border: 1px solid #a38d5e;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.toc, .toccolours {&lt;br /&gt;
  background: #e9dcc1;&lt;br /&gt;
  border: 1px solid #a38d5e;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
figure[typeof~=&amp;quot;mw:File/Thumb&amp;quot;], figure[typeof~=&amp;quot;mw:File/Frame&amp;quot;] {&lt;br /&gt;
  background: #e9dcc1;&lt;br /&gt;
  border: 1px solid #a38d5e;&lt;br /&gt;
  border-bottom: 0px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
figure[typeof~=&amp;quot;mw:File/Thumb&amp;quot;] &amp;gt; figcaption, figure[typeof~=&amp;quot;mw:File/Frame&amp;quot;] &amp;gt; figcaption {&lt;br /&gt;
  background: #e9dcc1;&lt;br /&gt;
  border: 1px solid #a38d5e;&lt;br /&gt;
  border-top: 0px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
figure[typeof~=&amp;quot;mw:File/Thumb&amp;quot;] &amp;gt; :not(figcaption) .mw-file-element, figure[typeof~=&amp;quot;mw:File/Frame&amp;quot;] &amp;gt; :not(figcaption) .mw-file-element {&lt;br /&gt;
  background: #e9dcc1;&lt;br /&gt;
  border: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
pre, code, .mw-code {&lt;br /&gt;
  background: #e9dcc1;&lt;br /&gt;
  border: 1px solid #a38d5e;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vector-legacy-sidebar .vector-menu-portal {&lt;br /&gt;
  box-shadow: inset #dbc498 0 0 0 2px, 0px 0px 6px #000;&lt;br /&gt;
  border: 2px solid #191b22;&lt;br /&gt;
  background: #e9dcc1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vector-legacy-sidebar .vector-menu-portal .vector-menu-heading {&lt;br /&gt;
  color: #222;&lt;br /&gt;
  background-image: linear-gradient(to right,rgba(20,20,20,0) 0,#a38d5e 33%,#a38d5e 66%,rgba(20,20,20,0) 100%);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vector-menu-tabs-legacy .selected {&lt;br /&gt;
  background-image: none;&lt;br /&gt;
  background: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vector-menu-tabs-legacy li {&lt;br /&gt;
  background-image: none;&lt;br /&gt;
  background: none;&lt;br /&gt;
  font-weight: bold;&lt;br /&gt;
  color: #eee;&lt;br /&gt;
  text-shadow: 0 0 10px #000, 0 0 10px #000, 0 0 10px #000;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vector-menu-tabs-legacy .selected a {&lt;br /&gt;
  color: #aee;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vector-menu-tabs-legacy .selected a:visited {&lt;br /&gt;
  color: #aee;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vector-menu-tabs-legacy .new a {&lt;br /&gt;
  color: inherit;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vector-menu-tabs-legacy li a {&lt;br /&gt;
  color: inherit;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vector-menu-tabs, .vector-menu-tabs a, #mw-head .vector-menu-dropdown .vector-menu-heading {&lt;br /&gt;
  background-image: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vector-menu-dropdown {&lt;br /&gt;
  background-image: none;&lt;br /&gt;
  font-weight: bold;&lt;br /&gt;
  color: #eee;&lt;br /&gt;
  text-shadow: 0 0 10px #000, 0 0 10px #000, 0 0 10px #000;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vector-menu-dropdown .vector-menu-heading {&lt;br /&gt;
  color: inherit;&lt;br /&gt;
  font-weight: inherit;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vector-menu-dropdown .vector-menu-content {&lt;br /&gt;
  box-shadow: inset #dbc498 0 0 0 2px, 0px 0px 6px #000;&lt;br /&gt;
  border: 2px solid #191b22;&lt;br /&gt;
  background: #e9dcc1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vector-menu-dropdown .mw-list-item a {&lt;br /&gt;
  color: #222;&lt;br /&gt;
  text-shadow: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vector-search-box {&lt;br /&gt;
  background-image: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#p-personal {&lt;br /&gt;
  box-shadow: inset #dbc498 0 0 0 2px, 0px 0px 6px #000;&lt;br /&gt;
  border: 2px solid #191b22;&lt;br /&gt;
  background: #e9dcc1;&lt;br /&gt;
  background: none;&lt;br /&gt;
  border: none;&lt;br /&gt;
  box-shadow: none;&lt;br /&gt;
  color: #eee;&lt;br /&gt;
  font-weight: bold;&lt;br /&gt;
  text-shadow: 0 0 10px #000, 0 0 10px #000;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#p-personal a.new {&lt;br /&gt;
  color:inherit;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#p-personal a:visited {&lt;br /&gt;
  color:inherit;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#p-personal a {&lt;br /&gt;
  color:inherit;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jamesp1989</name></author>
	</entry>
	<entry>
		<id>https://necessewiki.com/mediawiki/index.php?title=Modding/draft&amp;diff=24670</id>
		<title>Modding/draft</title>
		<link rel="alternate" type="text/html" href="https://necessewiki.com/mediawiki/index.php?title=Modding/draft&amp;diff=24670"/>
		<updated>2026-01-16T04:41:14Z</updated>

		<summary type="html">&lt;p&gt;Jamesp1989: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot; inline&amp;gt;lambda x: x * 2&amp;lt;/syntaxhighlight&amp;gt; is a [[w:Lambda (programming)|lambda expression]] in Python.&lt;/div&gt;</summary>
		<author><name>Jamesp1989</name></author>
	</entry>
	<entry>
		<id>https://necessewiki.com/mediawiki/index.php?title=Modding/draft&amp;diff=24669</id>
		<title>Modding/draft</title>
		<link rel="alternate" type="text/html" href="https://necessewiki.com/mediawiki/index.php?title=Modding/draft&amp;diff=24669"/>
		<updated>2026-01-16T04:39:36Z</updated>

		<summary type="html">&lt;p&gt;Jamesp1989: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;syntaxhighlight lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php echo &amp;quot;hello&amp;quot;;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jamesp1989</name></author>
	</entry>
	<entry>
		<id>https://necessewiki.com/mediawiki/index.php?title=Battle_Chef&amp;diff=24665</id>
		<title>Battle Chef</title>
		<link rel="alternate" type="text/html" href="https://necessewiki.com/mediawiki/index.php?title=Battle_Chef&amp;diff=24665"/>
		<updated>2026-01-14T13:40:05Z</updated>

		<summary type="html">&lt;p&gt;Jamesp1989: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Infobox mob&lt;br /&gt;
|name   = {{FULLPAGENAME}}&lt;br /&gt;
|image  = {{FULLPAGENAME}}.png&lt;br /&gt;
|type   = Monsters&lt;br /&gt;
|health = 900&lt;br /&gt;
|armor  = 30&lt;br /&gt;
|damage = ?&lt;br /&gt;
|speed  = ?&lt;br /&gt;
|drops  = &#039;&#039;&#039;Drops one of the following:&#039;&#039;&#039; {{Item|Battle Chef&#039;s Hat|addon=33.⅓%|}} {{Item|Battle Chef&#039;s Chestplate|addon=33.⅓%}} {{Item|Battle Chef&#039;s Boots|addon=33.⅓%}}&lt;br /&gt;
&#039;&#039;&#039;And if your lucky:&#039;&#039;&#039;&lt;br /&gt;
{{Item|Rolling Pin|addon=2%}}&lt;br /&gt;
{{Item|Butcher&#039;s Cleaver|addon=2%}}&lt;br /&gt;
{{Item|Chef&#039;s Special|addon=0.5%}}&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Monsters]]&lt;br /&gt;
&lt;br /&gt;
[[{{FULLPAGENAME}}]] is an enemy found during [[Incursions]], in Chef invasions.&lt;/div&gt;</summary>
		<author><name>Jamesp1989</name></author>
	</entry>
	<entry>
		<id>https://necessewiki.com/mediawiki/index.php?title=Battle_Chef&amp;diff=24664</id>
		<title>Battle Chef</title>
		<link rel="alternate" type="text/html" href="https://necessewiki.com/mediawiki/index.php?title=Battle_Chef&amp;diff=24664"/>
		<updated>2026-01-14T13:39:23Z</updated>

		<summary type="html">&lt;p&gt;Jamesp1989: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Infobox mob&lt;br /&gt;
|name   = {{FULLPAGENAME}}&lt;br /&gt;
|image  = {{FULLPAGENAME}}.png&lt;br /&gt;
|type   = Monsters&lt;br /&gt;
|health = 900&lt;br /&gt;
|armor  = 30&lt;br /&gt;
|damage = ?&lt;br /&gt;
|speed  = ?&lt;br /&gt;
|drops  = &#039;&#039;&#039;Drops one of the following:&#039;&#039;&#039; {{Item|Battle Chef&#039;s Hat|addon=33.⅓%|}} {{Item|Battle Chef&#039;s Chestplate|addon=33.⅓%}} {{Item|Battle Chef&#039;s Boots|addon=33.⅓%}}&lt;br /&gt;
&#039;&#039;&#039;and if your lucky:&#039;&#039;&#039;&lt;br /&gt;
{{Item|Rolling Pin|addon=2%}}&lt;br /&gt;
{{Item|Butcher&#039;s Cleaver|addon=2%}}&lt;br /&gt;
{{Item|Chef&#039;s Special|addon=0.5%}}&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Monsters]]&lt;br /&gt;
&lt;br /&gt;
[[{{FULLPAGENAME}}]] is an enemy found during [[Incursions]], in Chef invasions.&lt;/div&gt;</summary>
		<author><name>Jamesp1989</name></author>
	</entry>
	<entry>
		<id>https://necessewiki.com/mediawiki/index.php?title=Battle_Chef&amp;diff=24663</id>
		<title>Battle Chef</title>
		<link rel="alternate" type="text/html" href="https://necessewiki.com/mediawiki/index.php?title=Battle_Chef&amp;diff=24663"/>
		<updated>2026-01-14T13:37:23Z</updated>

		<summary type="html">&lt;p&gt;Jamesp1989: added additional drop items&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Infobox mob&lt;br /&gt;
|name   = {{FULLPAGENAME}}&lt;br /&gt;
|image  = {{FULLPAGENAME}}.png&lt;br /&gt;
|type   = Monsters&lt;br /&gt;
|health = 900&lt;br /&gt;
|armor  = 30&lt;br /&gt;
|damage = ?&lt;br /&gt;
|speed  = ?&lt;br /&gt;
|drops  = &#039;&#039;&#039;Drops one of the following:&#039;&#039;&#039; {{Item|Battle Chef&#039;s Hat|addon=33.⅓%|}} {{Item|Battle Chef&#039;s Chestplate|addon=33.⅓%}} {{Item|Battle Chef&#039;s Boots|addon=33.⅓%}}&lt;br /&gt;
{{Item|Rolling Pin|addon=2%}}&lt;br /&gt;
{{Item|Butcher&#039;s Cleaver|addon=2%}}&lt;br /&gt;
{{Item|Chef&#039;s Special|addon=0.5%}}&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Monsters]]&lt;br /&gt;
&lt;br /&gt;
[[{{FULLPAGENAME}}]] is an enemy found during [[Incursions]], in Chef invasions.&lt;/div&gt;</summary>
		<author><name>Jamesp1989</name></author>
	</entry>
	<entry>
		<id>https://necessewiki.com/mediawiki/index.php?title=Module:NecesseCache&amp;diff=24633</id>
		<title>Module:NecesseCache</title>
		<link rel="alternate" type="text/html" href="https://necessewiki.com/mediawiki/index.php?title=Module:NecesseCache&amp;diff=24633"/>
		<updated>2026-01-11T16:23:26Z</updated>

		<summary type="html">&lt;p&gt;Jamesp1989: Undo revision 24632 by Jamesp1989 (talk)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;local p = {}&lt;br /&gt;
&lt;br /&gt;
function p.loadItems()&lt;br /&gt;
	return load(&#039;necesse_items&#039;, &#039;Module:NecesseItems/data&#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.purgeItems()&lt;br /&gt;
	mw.ext.LuaCache.delete(&#039;necesse_items&#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.loadRecipes()&lt;br /&gt;
	return load(&#039;necesse_recipes&#039;, &#039;Module:NecesseRecipes/data&#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.purgeRecipes()&lt;br /&gt;
	mw.ext.LuaCache.delete(&#039;necesse_recipes&#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function load(cache, module)&lt;br /&gt;
	-- First try to load it from the cache&lt;br /&gt;
	local success, result = pcall(function()&lt;br /&gt;
		return mw.text.jsonDecode(mw.ext.LuaCache.get(cache))&lt;br /&gt;
	end)&lt;br /&gt;
	if success and result then&lt;br /&gt;
		return result&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- Now load it from the module and cache it&lt;br /&gt;
	local data = require(module)&lt;br /&gt;
	mw.ext.LuaCache.set(cache, mw.text.jsonEncode(data))&lt;br /&gt;
	return data&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Jamesp1989</name></author>
	</entry>
	<entry>
		<id>https://necessewiki.com/mediawiki/index.php?title=Module:NecesseCache&amp;diff=24632</id>
		<title>Module:NecesseCache</title>
		<link rel="alternate" type="text/html" href="https://necessewiki.com/mediawiki/index.php?title=Module:NecesseCache&amp;diff=24632"/>
		<updated>2026-01-11T16:17:35Z</updated>

		<summary type="html">&lt;p&gt;Jamesp1989: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;local p = {}&lt;br /&gt;
&lt;br /&gt;
function p.loadItems()&lt;br /&gt;
	return load(&#039;necesse_items&#039;, &#039;Module:NecesseItems/data&#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.purgeItems()&lt;br /&gt;
	mw.ext.LuaCache.delete(&#039;necesse_items&#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.loadRecipes()&lt;br /&gt;
	return load(&#039;necesse_recipes&#039;, &#039;Module:NecesseRecipes/data&#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.purgeRecipes()&lt;br /&gt;
	mw.ext.LuaCache.delete(&#039;necesse_recipes&#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.loadPlacement()&lt;br /&gt;
    return load(&#039;necesse_placement&#039;, &#039;Module:NecessePlacement/data&#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.purgePlacement()&lt;br /&gt;
    mw.ext.LuaCache.delete(&#039;necesse_placement&#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function load(cache, module)&lt;br /&gt;
	-- First try to load it from the cache&lt;br /&gt;
	local success, result = pcall(function()&lt;br /&gt;
		return mw.text.jsonDecode(mw.ext.LuaCache.get(cache))&lt;br /&gt;
	end)&lt;br /&gt;
	if success and result then&lt;br /&gt;
		return result&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- Now load it from the module and cache it&lt;br /&gt;
	local data = require(module)&lt;br /&gt;
	mw.ext.LuaCache.set(cache, mw.text.jsonEncode(data))&lt;br /&gt;
	return data&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Jamesp1989</name></author>
	</entry>
	<entry>
		<id>https://necessewiki.com/mediawiki/index.php?title=User:Jamesp1989&amp;diff=24631</id>
		<title>User:Jamesp1989</title>
		<link rel="alternate" type="text/html" href="https://necessewiki.com/mediawiki/index.php?title=User:Jamesp1989&amp;diff=24631"/>
		<updated>2026-01-11T16:14:46Z</updated>

		<summary type="html">&lt;p&gt;Jamesp1989: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[{{FULLPAGENAME}}/LODRAFT]]&lt;br /&gt;
&lt;br /&gt;
{{#invoke:NecessePlacement|formatValidTiles|palmsapling}}&lt;/div&gt;</summary>
		<author><name>Jamesp1989</name></author>
	</entry>
	<entry>
		<id>https://necessewiki.com/mediawiki/index.php?title=Multiplayer&amp;diff=24618</id>
		<title>Multiplayer</title>
		<link rel="alternate" type="text/html" href="https://necessewiki.com/mediawiki/index.php?title=Multiplayer&amp;diff=24618"/>
		<updated>2026-01-10T22:18:36Z</updated>

		<summary type="html">&lt;p&gt;Jamesp1989: /* Rent a dedicated server */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This article covers the complete setup process for a Necesse Dedicated server.&lt;br /&gt;
&lt;br /&gt;
If you want to set up a Linux dedicated server specifically, you can follow [[Multiplayer-Linux|this guide]].&lt;br /&gt;
&lt;br /&gt;
中文开服教程请参考：[[Multiplayer Chinese]]&lt;br /&gt;
&lt;br /&gt;
==Dedicated Server vs in-game world hosting==&lt;br /&gt;
It is not necessary to have a dedicated server in order to play multiplayer with others. Players can host their worlds in-game as well. A hosted world will be hosted on Steam, specifically in the location of your download region.&lt;br /&gt;
&lt;br /&gt;
The one advantage a dedicated server offers is the server/world will always be online and accessible. In the case of world hosting, the owner of the world will need to be online and in the world for other players to join. &lt;br /&gt;
&lt;br /&gt;
If your group won&#039;t be playing if the owner isn&#039;t online, your group can opt for in-game hosting instead.&lt;br /&gt;
&lt;br /&gt;
== Rent a dedicated server ==&lt;br /&gt;
If you&#039;d rather rent a dedicated game server hosted by a 3rd party, by making a purchase through this Shockbyte link you will support the developers of Necesse:&lt;br /&gt;
&lt;br /&gt;
* [https://shockbyte.com/partner/necesse Shockbyte]&lt;br /&gt;
&lt;br /&gt;
Other options are:&lt;br /&gt;
&lt;br /&gt;
* [https://pingperfect.com/gameservers/necesse-game-server-hosting.php Pingperfect]&lt;br /&gt;
* [https://www.bisecthosting.com/game-server-hosting BisectHosting]&lt;br /&gt;
* [https://citadelservers.com/game-servers/necesse-hosting CitadelServers]&lt;br /&gt;
* [https://www.gamehostbros.com/necesse-server-hosting/ Game Host Bros]&lt;br /&gt;
* [https://aagamehosting.com/game-servers/necesse-hosting AA Game Hosting]&lt;br /&gt;
* [https://berrybyte.net/necesse-server-hosting berrybyte]&lt;br /&gt;
* [https://www.kinetichosting.com/game-servers/necesse/order Kinetic Hosting]&lt;br /&gt;
* [https://wabbanode.com/games/necesse-server-hosting Wabbanode]&lt;br /&gt;
* [https://supercraft.host/necesse-server-hosting Supercraft]&lt;br /&gt;
* Any VPS hosting service, like AWS EC2&lt;br /&gt;
&lt;br /&gt;
== Downloading Server Files ==&lt;br /&gt;
&lt;br /&gt;
Downloading the server files can be performed in two different ways, which are:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Through Steam&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Navigate to your Steam library and filter for tools&lt;br /&gt;
[[File:Filter for Tools.png|thumb]]&lt;br /&gt;
&lt;br /&gt;
Identify &#039;Necesse Dedicated Server&#039; and click install&lt;br /&gt;
[[File:Download Necesse Dedicated Server.png|thumb]]&lt;br /&gt;
&lt;br /&gt;
[[File:Necesse Dedicated Server via Steam.png|thumb]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Through SteamCMD&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
See Valve&#039;s developer wiki for how to download and install SteamCMD: https://developer.valvesoftware.com/wiki/SteamCMD&lt;br /&gt;
&lt;br /&gt;
Once installed, run SteamCMD by double-clicking the steamcmd.exe in the installation folder.&lt;br /&gt;
&lt;br /&gt;
In the SteamCMD window, type in the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;login anonymous&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To change where the dedicated server is installed, use the command force_install_dir C:\Necesse&lt;br /&gt;
That would tell SteamCMD to install the Necesse Dedicated server files to a folder called Necesse on your PC&#039;s C drive&lt;br /&gt;
&lt;br /&gt;
Next, download the server files to the specified folder by typing:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;app_update 1169370 validate&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When the process has completed, it will say &amp;quot;Success! App &#039;1169370&#039; fully installed.&amp;quot; You can then close Steam CMD by typing:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;quit&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Through download&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
You can also download the server files located at https://necessegame.com/server/&lt;br /&gt;
&lt;br /&gt;
== Port Forwarding ==&lt;br /&gt;
&lt;br /&gt;
The protocol and default port for Necesse is UDP and port 14159.  You will need to open these ports on your router and server&#039;s Windows Firewall.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Router&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Login to your router.&lt;br /&gt;
&lt;br /&gt;
Navigate to your routers port forwarding section.&lt;br /&gt;
&lt;br /&gt;
Create the port forward entries in your router.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Windows Firewall&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Navigate to Control Panel → System and Security → Windows Firewall.&lt;br /&gt;
&lt;br /&gt;
Select &amp;quot;Advanced settings&amp;quot; and highlight &amp;quot;Inbound Rules&amp;quot; in the left pane.&lt;br /&gt;
&lt;br /&gt;
Right click Inbound Rules and select &amp;quot;New Rule...&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Click the &amp;quot;Port&amp;quot; circle and click &amp;quot;Next&amp;quot;&lt;br /&gt;
[[File:Firewall Select &amp;quot;Port&amp;quot;.png|thumb]]&lt;br /&gt;
&lt;br /&gt;
Select the protocol (UDP) and the port number (if you&#039;ve followed this example, it would be 14159) in the &amp;quot;Specific local ports:&amp;quot; text box and click Next.&lt;br /&gt;
&lt;br /&gt;
Select &amp;quot;Allow the connection&amp;quot; in the next window and click Next.&lt;br /&gt;
&lt;br /&gt;
Select the network type as you see fit and click Next.&lt;br /&gt;
&lt;br /&gt;
Name the rule &amp;quot;Necesse Server&amp;quot; and click Finish.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Port Forwarding Testing&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Test that your ports are forwarded correctly by entering your public IP address and the port number on this site: https://portchecker.co/&lt;br /&gt;
&lt;br /&gt;
Note that port checkers sometimes report false negatives, if you have done everything correct and you can see your server listening on a netstat scan, it may be worth checking if people can join anyway.&lt;br /&gt;
&lt;br /&gt;
== Running the server ==&lt;br /&gt;
To run the server, navigate to wherever you installed the server files, if you&#039;ve followed the exact steps from this guide, it would be C:\Necesse&lt;br /&gt;
&lt;br /&gt;
Locate the file called &amp;quot;StartServer.bat&amp;quot; and double-click it, a new window will appear, this is the dedicated server program.&lt;br /&gt;
&lt;br /&gt;
You will be asked to name the world, type your desired world name into the text box and click &amp;quot;Enter&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If you want custom server options, type in &amp;quot;y&amp;quot; and click &amp;quot;Enter&amp;quot;, if you do not, type &amp;quot;n&amp;quot; and click &amp;quot;Enter&amp;quot;&lt;br /&gt;
&lt;br /&gt;
It will ask you to specify the &amp;quot;host port&amp;quot; this is the port we forwarded earlier, so type in 14159 and then click &amp;quot;Enter&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Then, it will ask for the amount of player slots, type in a number between 1 and 250, and click &amp;quot;Enter&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Next, it will ask whether you want a server password, if you do, type in the server password, don&#039;t type anything if you don&#039;t want a server password, and click &amp;quot;Enter&amp;quot;&lt;br /&gt;
&lt;br /&gt;
It will ask you to specify custom spawn island, leave blank for random or enter a custom spawn island in the format: &amp;lt;x&amp;gt;,&amp;lt;y&amp;gt; and click &amp;quot;Enter&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Then you&#039;ll be asked to specify spawn seed, enter a random number or leave blank for random, and click &amp;quot;Enter&amp;quot;&lt;br /&gt;
&lt;br /&gt;
You&#039;ll then be asked to choose whether to spawn the guide house, type in &amp;quot;y&amp;quot; for yes or &amp;quot;n&amp;quot; for no, and click &amp;quot;Enter&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Click &amp;quot;Enter&amp;quot; one final time, to start up the server.&lt;br /&gt;
&lt;br /&gt;
Leave the dedicated server program window open to keep the server running, when you want to shut down the server, type &amp;quot;quit&amp;quot; into the text box and click &amp;quot;Enter&amp;quot; or click the X at the top right of the window.&lt;br /&gt;
&lt;br /&gt;
== How to join the server ==&lt;br /&gt;
* Run the game from Steam&lt;br /&gt;
&lt;br /&gt;
* Click &amp;quot;Multiplayer&amp;quot;&lt;br /&gt;
&lt;br /&gt;
* Click &amp;quot;Add Server&amp;quot;&lt;br /&gt;
&lt;br /&gt;
* Type a name that will help you remember the server in the &amp;quot;Name&amp;quot; field&lt;br /&gt;
&lt;br /&gt;
* Type your &#039;&#039;&#039;public IPv4 address&#039;&#039;&#039; (which can be found here: https://whatismyipaddress.com/) in the &amp;quot;IP address&amp;quot; field. IPs in the &#039;&#039;&#039;192.168.0.0-192.168.255.255 range are private&#039;&#039;&#039;, and others will not be able to connect to it unless they&#039;re on the same network.&lt;br /&gt;
&lt;br /&gt;
* Type your server port which if you&#039;ve followed this guide is 14159 in the &amp;quot;Port Number&amp;quot; field&lt;br /&gt;
&lt;br /&gt;
* Click &amp;quot;Add&amp;quot;&lt;br /&gt;
&lt;br /&gt;
* Your server will now appear in the &amp;quot;Multiplayer&amp;quot; menu, double-click it to join (or click it once then click &amp;quot;Join Server&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
== Configuring the server ==&lt;br /&gt;
If you want to change the configuration of your server (after the initial setup) you will need to edit some files. They can be edited using any Text Editor program, such as Notepad (pre-installed to all Windows based PC&#039;s)&lt;br /&gt;
&lt;br /&gt;
Before editing any configuration files, you should ALWAYS stop your server first.&lt;br /&gt;
&lt;br /&gt;
To navigate to the server&#039;s configuration files (and save files) type %appdata% into the Windows search bar, then double-click the &amp;quot;Necesse&amp;quot; folder&lt;br /&gt;
&lt;br /&gt;
The server configuration file is named &amp;quot;server.cfg&amp;quot; and is located at C:\Users\YourPCUsernameHere\AppData\Roaming\Necesse\cfg&lt;br /&gt;
&lt;br /&gt;
The world configuration file is named &amp;quot;worldSettings.cfg&amp;quot; and is located at C:\Users\YourPCUsernameHere\AppData\Roaming\Necesse\saves\YourWorldNamehere.zip&lt;br /&gt;
&lt;br /&gt;
The world is in a Compressed (zipped) .zip folder by default, meaning you will have to extract the files contained inside by right-clicking and selecting &amp;quot;Extract Here&amp;quot; - rename the original YourWorldNameHere.zip to something different.&lt;br /&gt;
&lt;br /&gt;
Then you need to edit the &amp;quot;worldSettings.cfg&amp;quot; file.&lt;br /&gt;
&lt;br /&gt;
Then right-click the YourWorldNameHere folder, and hover over &amp;quot;Send to&amp;quot; and click &amp;quot;Compressed (zipped) folder&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== File Locations ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;By default&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The server configuration file is named &amp;quot;server.cfg&amp;quot; and is located at C:\Users\YourPCUsernameHere\AppData\Roaming\Necesse\cfg&lt;br /&gt;
&lt;br /&gt;
The world configuration file is named &amp;quot;worldSettings.cfg&amp;quot; and is located at C:\Users\YourPCUsernameHere\AppData\Roaming\Necesse\saves\YourWorldNamehere.zip&lt;br /&gt;
&lt;br /&gt;
The save data is the .zip named according to the world name, and is located at C:\Users\YourPCUsernameHere\AppData\Roaming\Necesse\saves\&lt;br /&gt;
&lt;br /&gt;
The server logs are found at C:\Users\YourPCUsernameHere\AppData\Roaming\Necesse\logs&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Customizations&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Forcing configs to the game directory can be done with the -localdir parameter in bat file&lt;br /&gt;
&lt;br /&gt;
== Server and chat commands ==&lt;br /&gt;
&lt;br /&gt;
Commands can be run from the server command line, or from the in-game chat if the user have the required permissions.&lt;br /&gt;
If you are hosting or playing singleplayer, you have all command permissions. When joining a server, you start with user permissions. Permissions can be assigned with the &amp;lt;code&amp;gt;/permissions set &amp;lt;name&amp;gt; &amp;lt;permission&amp;gt;&amp;lt;/code&amp;gt; command. If you start the server with the &amp;lt;code&amp;gt;-owner &amp;lt;name&amp;gt;&amp;lt;/code&amp;gt; launch option, any player joining with this name will get owner permissions.&lt;br /&gt;
&lt;br /&gt;
Commands that require cheats enabled will give a warning before attempting to use them. Using them will disable achievements on the world in which you use them.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Command || Permissions || Action || Cheats&lt;br /&gt;
|-&lt;br /&gt;
| /help [&amp;lt;page/command&amp;gt;] || User || Lists all commands or gives information about a specific command || &lt;br /&gt;
|-&lt;br /&gt;
| /playtime  || User || Shows your current playtime on the server || &lt;br /&gt;
|-&lt;br /&gt;
| /me &amp;lt;action&amp;gt; || User || Declare an action to the entire server || &lt;br /&gt;
|-&lt;br /&gt;
| /w, /whisper or /pm &amp;lt;player&amp;gt; &amp;lt;message&amp;gt; || User || Whisper a message to another player || &lt;br /&gt;
|-&lt;br /&gt;
| /mypermissions  || User || Shows your permission level || &lt;br /&gt;
|-&lt;br /&gt;
| /die  || User || Kills yourself || &lt;br /&gt;
|-&lt;br /&gt;
| /performance [&amp;lt;includeServer&amp;gt;] [&amp;lt;seconds&amp;gt;] || User || Records server performance over some seconds and creates a file with the results || &lt;br /&gt;
|-&lt;br /&gt;
| /createteam  || User || Creates a new team for yourself || &lt;br /&gt;
|-&lt;br /&gt;
| /leaveteam  || User || Leaves your current team || &lt;br /&gt;
|-&lt;br /&gt;
| /invite &amp;lt;player&amp;gt; || User || Invites a player to your team || &lt;br /&gt;
|-&lt;br /&gt;
| /network  || Moderator || Shows network usage this session || &lt;br /&gt;
|-&lt;br /&gt;
| /players  || Moderator || Lists players currently online || &lt;br /&gt;
|-&lt;br /&gt;
| /playernames  || Moderator || Lists all authentications and their names || &lt;br /&gt;
|-&lt;br /&gt;
| /levels  || Moderator || Lists currently loaded levels || &lt;br /&gt;
|-&lt;br /&gt;
| /save  || Moderator || Saves all data || &lt;br /&gt;
|-&lt;br /&gt;
| /kick &amp;lt;player&amp;gt; [&amp;lt;message/reason&amp;gt;] || Moderator || Kicks player from the server || &lt;br /&gt;
|-&lt;br /&gt;
| /say &amp;lt;message&amp;gt; || Moderator || Talks in the chat as Server || &lt;br /&gt;
|-&lt;br /&gt;
| /mow &amp;lt;range&amp;gt; [&amp;lt;chance&amp;gt;] || Admin || Mows ground of grass in range with percent chance || ✓&lt;br /&gt;
|-&lt;br /&gt;
| /time &amp;lt;set/add&amp;gt; [&amp;lt;amount&amp;gt;] || Admin || Sets/adds world time (can use (mid)day or (mid)night) || ✓&lt;br /&gt;
|-&lt;br /&gt;
| /clearall [&amp;lt;global&amp;gt;] || Admin || Clears all entities || ✓&lt;br /&gt;
|-&lt;br /&gt;
| /clearmobs [&amp;lt;global&amp;gt; [&amp;lt;type&amp;gt;]] || Admin || Clears all mobs or a specific type on your level or on all loaded levels || ✓&lt;br /&gt;
|-&lt;br /&gt;
| /clearevents [&amp;lt;global&amp;gt; [&amp;lt;type&amp;gt;]] || Admin || Clears all events on your level or on all loaded levels || ✓&lt;br /&gt;
|-&lt;br /&gt;
| /tp [&amp;lt;player1&amp;gt;] &amp;lt;player2/home/death/spawn&amp;gt; || Admin || Teleports player1 to player2 or other location || ✓&lt;br /&gt;
|-&lt;br /&gt;
| /print &amp;lt;message&amp;gt; || Admin || Prints a message in the chat || &lt;br /&gt;
|-&lt;br /&gt;
| /give [&amp;lt;player&amp;gt;] &amp;lt;item&amp;gt; [&amp;lt;amount&amp;gt;] || Admin || Gives item to player || ✓&lt;br /&gt;
|-&lt;br /&gt;
| /buff [&amp;lt;player&amp;gt;] &amp;lt;buff&amp;gt; [&amp;lt;seconds&amp;gt;] || Admin || Gives buff to player || ✓&lt;br /&gt;
|-&lt;br /&gt;
| /clearbuff [&amp;lt;player&amp;gt;] &amp;lt;buff&amp;gt; || Admin || Clears buff from player || ✓&lt;br /&gt;
|-&lt;br /&gt;
| /reveal [&amp;lt;player&amp;gt;] || Admin || Reveals entire clients current level || ✓&lt;br /&gt;
|-&lt;br /&gt;
| /setisland [&amp;lt;player&amp;gt;] &amp;lt;islandX&amp;gt; &amp;lt;islandY&amp;gt; [&amp;lt;dimension&amp;gt;] || Admin || Changes the island of the player || ✓&lt;br /&gt;
|-&lt;br /&gt;
| /setdimension [&amp;lt;player&amp;gt;] &amp;lt;dimension&amp;gt; || Admin || Changes the dimension of player || ✓&lt;br /&gt;
|-&lt;br /&gt;
| /hp [&amp;lt;player&amp;gt;] &amp;lt;health&amp;gt; || Admin || Sets the health of player || ✓&lt;br /&gt;
|-&lt;br /&gt;
| /maxhp [&amp;lt;player&amp;gt;] &amp;lt;health&amp;gt; || Admin || Sets the max health of player || ✓&lt;br /&gt;
|-&lt;br /&gt;
| /mana [&amp;lt;player&amp;gt;] &amp;lt;mana&amp;gt; || Admin || Sets the mana of player || ✓&lt;br /&gt;
|-&lt;br /&gt;
| /maxmana [&amp;lt;player&amp;gt;] &amp;lt;mana&amp;gt; || Admin || Sets the max mana of player || ✓&lt;br /&gt;
|-&lt;br /&gt;
| /hunger [&amp;lt;player&amp;gt;] &amp;lt;hunger&amp;gt; || Admin || Sets the hunger percent of player || ✓&lt;br /&gt;
|-&lt;br /&gt;
| /deleteplayer &amp;lt;authentication/fullname&amp;gt; || Admin || Deletes a players files in the saved players folder || &lt;br /&gt;
|-&lt;br /&gt;
| /settings &amp;lt;list/setting&amp;gt; [&amp;lt;arg&amp;gt;] || Admin || Change server world settings || &lt;br /&gt;
|-&lt;br /&gt;
| /difficulty &amp;lt;list/difficulty&amp;gt; || Admin || Changes difficulty setting || &lt;br /&gt;
|-&lt;br /&gt;
| /deathpenalty &amp;lt;list/penalty&amp;gt; || Admin || Changes death penalty setting || &lt;br /&gt;
|-&lt;br /&gt;
| /raids &amp;lt;list/frequency&amp;gt; || Admin || Changes raids frequency setting || &lt;br /&gt;
|-&lt;br /&gt;
| /pausewhenempty &amp;lt;0/1&amp;gt; || Admin || Enable/disable pause when empty setting || &lt;br /&gt;
|-&lt;br /&gt;
| /maxlatency &amp;lt;seconds&amp;gt; || Admin || Sets the max latency before client timeout || &lt;br /&gt;
|-&lt;br /&gt;
| /ban &amp;lt;authentication/name&amp;gt; || Admin || Bans a player || &lt;br /&gt;
|-&lt;br /&gt;
| /unban &amp;lt;authentication/name&amp;gt; || Admin || Removes a ban || &lt;br /&gt;
|-&lt;br /&gt;
| /bans  || Admin || Lists all current bans || &lt;br /&gt;
|-&lt;br /&gt;
| /rain [&amp;lt;islandX&amp;gt; &amp;lt;islandY&amp;gt; &amp;lt;dimension&amp;gt;] &amp;lt;start/clear&amp;gt; || Admin || Sets the rain on the level || ✓&lt;br /&gt;
|-&lt;br /&gt;
| /enchant &amp;lt;clear/set/random&amp;gt; [&amp;lt;slot&amp;gt;] [&amp;lt;enchantID&amp;gt;] || Admin || Clears, sets or gives a random enchant (use -1 slot for selected item) || ✓&lt;br /&gt;
|-&lt;br /&gt;
| /copyitem [&amp;lt;slot&amp;gt;] || Admin || Copies an item and all of its data || ✓&lt;br /&gt;
|-&lt;br /&gt;
| /healmobs &amp;lt;health&amp;gt; [&amp;lt;range&amp;gt;] [&amp;lt;filter&amp;gt;] || Admin || Heals mobs around you || ✓&lt;br /&gt;
|-&lt;br /&gt;
| /copyplayer &amp;lt;from&amp;gt; &amp;lt;to&amp;gt; || Admin || Copy a players inventory, position and health over to another || ✓&lt;br /&gt;
|-&lt;br /&gt;
| /demo [&amp;lt;player&amp;gt;] [&amp;lt;setup&amp;gt; [&amp;lt;forceNew&amp;gt;]] [&amp;lt;builds&amp;gt;] || Admin || Setups up a world and/or build for player || ✓&lt;br /&gt;
|-&lt;br /&gt;
| /getteam &amp;lt;player&amp;gt; || Admin || Gets the current team of the player || &lt;br /&gt;
|-&lt;br /&gt;
| /clearteam &amp;lt;player&amp;gt; || Admin || Removes the player from his current team || &lt;br /&gt;
|-&lt;br /&gt;
| /setteam &amp;lt;player&amp;gt; &amp;lt;team&amp;gt; || Admin || Sets the team of the player. || &lt;br /&gt;
|-&lt;br /&gt;
| /setteamowner &amp;lt;team&amp;gt; &amp;lt;player&amp;gt; || Admin || Sets the owner of the team. The new owner must be part of the team already || &lt;br /&gt;
|-&lt;br /&gt;
| /motd &amp;lt;clear/get/message&amp;gt; || Admin || Sets or clears the message of the day. Use \n for new line || &lt;br /&gt;
|-&lt;br /&gt;
| /changename &amp;lt;player&amp;gt; &amp;lt;name&amp;gt; || Admin || Changes the name of a player || &lt;br /&gt;
|-&lt;br /&gt;
| /sharemap [&amp;lt;from&amp;gt;] &amp;lt;to&amp;gt; || Admin || Shares your map discoveries with another player || ✓&lt;br /&gt;
|-&lt;br /&gt;
| /stop, /exit or /quit  || Owner || Saves and stops the server || &lt;br /&gt;
|-&lt;br /&gt;
| /password [&amp;lt;password&amp;gt;] || Owner || Set a password of the server, blank will be no password || &lt;br /&gt;
|-&lt;br /&gt;
| /permissions &amp;lt;list/set/get&amp;gt; [&amp;lt;authentication/name&amp;gt; [&amp;lt;permissions&amp;gt;]] || Owner || Sets a players permissions || &lt;br /&gt;
|-&lt;br /&gt;
| /regen [&amp;lt;islandX&amp;gt; &amp;lt;islandY&amp;gt; &amp;lt;dimension&amp;gt;] [&amp;lt;biome&amp;gt;] [&amp;lt;seeded&amp;gt;] || Owner || Regenerates the entire level || ✓&lt;br /&gt;
|-&lt;br /&gt;
| /allowcheats  || Owner || Enables/allows cheats on this world (NOT REVERSIBLE) || ✓&lt;br /&gt;
|-&lt;br /&gt;
| /itemgnd [&amp;lt;slot&amp;gt;] &amp;lt;set/get/clear&amp;gt; [&amp;lt;key&amp;gt; [&amp;lt;value&amp;gt;]] || Owner || Gets or sets item GND data || ✓&lt;br /&gt;
|-&lt;br /&gt;
| /jobsearchrange &amp;lt;range&amp;gt; || Owner || Sets the job search tile range of settlers || &lt;br /&gt;
|-&lt;br /&gt;
| /language &amp;lt;language&amp;gt; || Server || Sets server language settings ||  &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Server Parameters ==&lt;br /&gt;
&lt;br /&gt;
The following parameters can be added to customize server configuration. Found in &amp;lt;code&amp;gt;Necesse.jar&amp;lt;/code&amp;gt; under &amp;lt;code&amp;gt;necesse.engine.platforms.desktop.server&amp;lt;/code&amp;gt; package, &amp;lt;code&amp;gt;DesktopServerWrapper.class&amp;lt;/code&amp;gt; file.&lt;br /&gt;
&lt;br /&gt;
Parameters not given will be loaded from server settings file.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Parameter || Description&lt;br /&gt;
|-&lt;br /&gt;
| -help || Shows this help menu&lt;br /&gt;
|-&lt;br /&gt;
| -nogui || Runs the server in terminal instead of opening the GUI&lt;br /&gt;
|-&lt;br /&gt;
| -settings &amp;lt;code&amp;gt;&amp;lt;file&amp;gt;&amp;lt;/code&amp;gt; || Settings file path to load server settings from&lt;br /&gt;
|-&lt;br /&gt;
| -world &amp;lt;code&amp;gt;&amp;lt;name&amp;gt;&amp;lt;/code&amp;gt; || World to load instead of being asked which to load&lt;br /&gt;
|-&lt;br /&gt;
| -port &amp;lt;code&amp;gt;&amp;lt;port&amp;gt;&amp;lt;/code&amp;gt; || Port to host at&lt;br /&gt;
|-&lt;br /&gt;
| -slots &amp;lt;code&amp;gt;&amp;lt;slots&amp;gt;&amp;lt;/code&amp;gt; || Amount of player slots&lt;br /&gt;
|-&lt;br /&gt;
| -owner &amp;lt;code&amp;gt;&amp;lt;name&amp;gt;&amp;lt;/code&amp;gt; || Anyone that connects with this name, will get owner permissions&lt;br /&gt;
|-&lt;br /&gt;
| -motd &amp;lt;code&amp;gt;&amp;lt;message&amp;gt;&amp;lt;/code&amp;gt; || Sets the message of the day. Use \\n for new line&lt;br /&gt;
|-&lt;br /&gt;
| -password &amp;lt;code&amp;gt;&amp;lt;password&amp;gt;&amp;lt;/code&amp;gt; || The password for the server, blank for no password&lt;br /&gt;
|-&lt;br /&gt;
| -pausewhenempty &amp;lt;code&amp;gt;&amp;lt;1/0&amp;gt;&amp;lt;/code&amp;gt; || Pauses the world when there are no players in server, defaults 0&lt;br /&gt;
|-`&lt;br /&gt;
| -giveclientspower &amp;lt;code&amp;gt;&amp;lt;1/0&amp;gt;&amp;lt;/code&amp;gt; || If the server should check client actions, a kind of anti-cheat. When off it will give a much smoother experience for clients. Defaults off.&lt;br /&gt;
|-&lt;br /&gt;
| -logging &amp;lt;code&amp;gt;&amp;lt;1/0&amp;gt;&amp;lt;/code&amp;gt; || If on the server will generate a log file for each session, defaults 1&lt;br /&gt;
|-&lt;br /&gt;
| -logs &amp;lt;code&amp;gt;&amp;lt;folder&amp;gt;&amp;lt;/code&amp;gt; || What folder to place the logs, if logging is enabled&lt;br /&gt;
|-&lt;br /&gt;
| -zipsaves &amp;lt;code&amp;gt;&amp;lt;1/0&amp;gt;&amp;lt;/code&amp;gt; || If saves should be compressed, defaults to 1&lt;br /&gt;
|-&lt;br /&gt;
| -language &amp;lt;code&amp;gt;&amp;lt;language&amp;gt;&amp;lt;/code&amp;gt; || Sets the language of the server, only used for occasional messages in log&lt;br /&gt;
|-&lt;br /&gt;
| -ip &amp;lt;code&amp;gt;&amp;lt;address&amp;gt;&amp;lt;/code&amp;gt; || Binds the server IP to the address&lt;br /&gt;
|-&lt;br /&gt;
| -datadir &amp;lt;code&amp;gt;&amp;lt;path&amp;gt;&amp;lt;/code&amp;gt; || Sets the path where cache, latest log, saves etc. are stored. Defaults to Necesse folder in appdata on different platforms&lt;br /&gt;
|-&lt;br /&gt;
| -localdir || Same as -datadir, but uses the local directory the server is launched from&lt;br /&gt;
|-&lt;br /&gt;
| -ignoreseasons || Disables seasonal content, e.g. [[Christmas Present]], [[Christmas Hat]], etc.&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Jamesp1989</name></author>
	</entry>
	<entry>
		<id>https://necessewiki.com/mediawiki/index.php?title=Crops&amp;diff=24606</id>
		<title>Crops</title>
		<link rel="alternate" type="text/html" href="https://necessewiki.com/mediawiki/index.php?title=Crops&amp;diff=24606"/>
		<updated>2026-01-08T16:29:24Z</updated>

		<summary type="html">&lt;p&gt;Jamesp1989: added beet seed&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Infobox item&lt;br /&gt;
|type           = [[Plants]]&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
[[Crops]] are used for [[cooking]]. They can be grown by planting [[Seeds|seeds]] in [[Farmland]]. When harvested, they will drop a random amount of [[Crops]] and 1 - 2 [[Seeds|seeds]]. Each crop has 5 growth stages, and the time it takes for one growth stage to complete is randomized each time it starts, somewhere between 7 and 10 minutes, and 4 and 7 minutes for Wheat.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The [[Fertilizer]] can be used on [[Crops]] to speed up growth.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Crops==&lt;br /&gt;
The &#039;&#039;&#039;Price&#039;&#039;&#039; listed below is the &#039;&#039;&#039;best price&#039;&#039;&#039; per single crop. &amp;lt;br&amp;gt;&lt;br /&gt;
An asterisk (*) in the &#039;&#039;&#039;Earning per harvest&#039;&#039;&#039; column means that a seed was excluded for replanting purposes. &lt;br /&gt;
* The &#039;&#039;&#039;Earning per harvest&#039;&#039;&#039; column excludes the earnings from selling extra seeds that could be dropped per harvest (all seeds from crops that don&#039;t exclusively drop seeds sell for the same price of 1 [[File:Coin_Currency.png]] and have the same drop chances).&lt;br /&gt;
&lt;br /&gt;
* There might be more profitable methods to use a crop (such as processing [[Rice Seeds]](1[[File:Coin_Currency.png]]) into [[Rice]] (3[[File:Coin_Currency.png]]) into selling.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ &lt;br /&gt;
|-&lt;br /&gt;
! Seed !! Growth !! Crop !! Drops !! Minutes per Drop !! Price !! Earning per harvest&lt;br /&gt;
|-&lt;br /&gt;
| {{Item|Cabbage Seeds|inline=1}} || [[File:Growing_Cabbage.gif]] || {{Item|Cabbage|inline=1}} || 1 - 2 || 17.5 - 25 || 2 [[File:Coin_Currency.png]] [[File:Pawnbroker.png]] || 2 - 4 [[File:Coin_Currency.png]]&lt;br /&gt;
|-&lt;br /&gt;
| {{Item|Carrot Seeds|inline=1}} || [[File:Growing_Carrot.gif]] || {{Item|Carrot|inline=1}} || 1 - 2 || 17.5 - 25 || 2 [[File:Coin_Currency.png]] [[File:Pawnbroker.png]] || 2 - 4 [[File:Coin_Currency.png]]&lt;br /&gt;
|-&lt;br /&gt;
| {{Item|Chili Pepper Seeds|inline=1}} || [[File:Growing_Chili_Pepper.gif]] || {{Item|Chili Pepper|inline=1}} || 1 - 3 || 11.67 - 16.67 || 2 [[File:Coin_Currency.png]] [[File:Pawnbroker.png]] || 2 - 6 [[File:Coin_Currency.png]]&lt;br /&gt;
|-&lt;br /&gt;
| {{Item|Coffee Beans|inline=1}} || [[File:Growing_Coffee_Beans.gif]] || {{Item|Coffee Beans|inline=1}} || 1 - 5 || 7 - 10 || 3 [[File:Coin_Currency.png]] [[File:Pawnbroker.png]] || 0 - 12 [[File:Coin_Currency.png]]*&lt;br /&gt;
|-&lt;br /&gt;
| {{Item|Corn Seeds|inline=1}} || [[File:Growing_Corn.gif]] || {{Item|Corn|inline=1}} || 1 - 3 || 11.67 - 16.67 || 2 [[File:Coin_Currency.png]] [[File:Pawnbroker.png]] || 2 - 6 [[File:Coin_Currency.png]]&lt;br /&gt;
|-&lt;br /&gt;
| {{Item|Eggplant Seeds|inline=1}} || [[File:Growing_Eggplant.gif]] || {{Item|Eggplant|inline=1}} || 1 - 2 || 17.5 - 25 || 2 [[File:Coin_Currency.png]] [[File:Pawnbroker.png]] || 2 - 4 [[File:Coin_Currency.png]]&lt;br /&gt;
|-&lt;br /&gt;
| {{Item|Onion Seeds|inline=1}} || [[File:Growing_Onion.gif]] || {{Item|Onion|inline=1}} || 1 - 2 || 17.5 - 25 || 3 [[File:Coin_Currency.png]] [[File:Pawnbroker.png]] || 3 - 6 [[File:Coin_Currency.png]]&lt;br /&gt;
|-&lt;br /&gt;
| {{Item|Potato Seeds|inline=1}} || [[File:Growing_Potato.gif]] || {{Item|Potato|inline=1}} || 1 - 3 || 11.67 - 16.67 || 2 [[File:Coin_Currency.png]] [[File:Pawnbroker.png]] || 2 - 6 [[File:Coin_Currency.png]]&lt;br /&gt;
|-&lt;br /&gt;
| {{Item|Pumpkin Seeds|inline=1}} || [[File:Growing_Pumpkin.gif]] || {{Item|Pumpkin|inline=1}} || 1 - 2 || 17.5 - 25 || 5 [[File:Coin_Currency.png]] [[File:Pawnbroker.png]] || 5 - 10 [[File:Coin_Currency.png]]&lt;br /&gt;
|-&lt;br /&gt;
| {{Item|Rice Seeds|inline=1}}|| [[File:Growing_Rice.gif]] || {{Item|Rice Seeds|inline=1}} || 2 - 5 || 11.67 - 16.67 || 1 [[File:Coin_Currency.png]] [[File:Pawnbroker.png]] || 1 - 4 [[File:Coin_Currency.png]]*&lt;br /&gt;
|-&lt;br /&gt;
| {{Item|Strawberry Seeds|inline=1}} || [[File:Growing_Strawberry.gif]] || {{Item|Strawberry|inline=1}} || 1 - 4 || 8.75 - 12.5 || 3 [[File:Coin_Currency.png]] [[File:Pawnbroker.png]] || 3 - 12 [[File:Coin_Currency.png]]&lt;br /&gt;
|-&lt;br /&gt;
| {{Item|Sugar Beet Seeds|inline=1}} || [[File:Growing_Sugar Beet.gif]] || {{Item|Sugar Beet|inline=1}} || 1 - 2 || 17.5 - 25 || 2 [[File:Coin_Currency.png]] [[File:Pawnbroker.png]] || 2 - 4 [[File:Coin_Currency.png]]&lt;br /&gt;
|-&lt;br /&gt;
| {{Item|Tomato Seeds|inline=1}} || [[File:Growing_Tomato.gif]] || {{Item|Tomato|inline=1}} || 1 - 3 || 11.67 - 16.67 || 2 [[File:Coin_Currency.png]] [[File:Pawnbroker.png]] || 2 - 6 [[File:Coin_Currency.png]]&lt;br /&gt;
|-&lt;br /&gt;
| {{Item|Beet Seeds|inline=1}} || [[File:Growing_Beet.gif]] || {{Item|Beet|inline=1}} || 1 - 2 || 5 - 8.75 || 9 [[File:Coin_Currency.png]] [[File:Farmer.png]] || 5-10 [[File:Coin_Currency.png]]&lt;br /&gt;
|-&lt;br /&gt;
| {{Item|Wheat Seeds|inline=1}} || [[File:Growing_Wheat.gif]] || {{Item|Wheat|inline=1}} || 1 - 4 || 5 - 8.75 || 9 [[File:Coin_Currency.png]] [[File:Farmer.png]] || 9 - 36 [[File:Coin_Currency.png]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:Plants]]&lt;/div&gt;</summary>
		<author><name>Jamesp1989</name></author>
	</entry>
	<entry>
		<id>https://necessewiki.com/mediawiki/index.php?title=Guide:Getting_Started/Taking_On_Evils_Protector&amp;diff=24600</id>
		<title>Guide:Getting Started/Taking On Evils Protector</title>
		<link rel="alternate" type="text/html" href="https://necessewiki.com/mediawiki/index.php?title=Guide:Getting_Started/Taking_On_Evils_Protector&amp;diff=24600"/>
		<updated>2026-01-06T18:49:02Z</updated>

		<summary type="html">&lt;p&gt;Jamesp1989: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Upgrading Our Gear==&lt;br /&gt;
{{ItemList|compact|&lt;br /&gt;
|&lt;br /&gt;
Now that we are back up on the surface we need to further upgrade and enchant our gear to prepare for the first boss. You need to have collected at least:  &lt;br /&gt;
*{{item|Frost Shard|48|inline=1}}&lt;br /&gt;
this is the minimum amount of materials required to craft:&lt;br /&gt;
* {{item|Frost Helmet|inline=1}} (as Im mostly melee focused but il get into more detail on that later).&lt;br /&gt;
* {{item|Frost Chestplate}}&lt;br /&gt;
* {{item|Frost Boots}}&lt;br /&gt;
* {{item|Frost Sword|inline=1}} (my melee weapon of choice)&lt;br /&gt;
}}&lt;br /&gt;
== Enchanting Our Gear ==&lt;br /&gt;
{{ItemList|compact|&lt;br /&gt;
|&lt;br /&gt;
&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Jamesp1989</name></author>
	</entry>
	<entry>
		<id>https://necessewiki.com/mediawiki/index.php?title=Incursion_tier_Armor&amp;diff=24599</id>
		<title>Incursion tier Armor</title>
		<link rel="alternate" type="text/html" href="https://necessewiki.com/mediawiki/index.php?title=Incursion_tier_Armor&amp;diff=24599"/>
		<updated>2026-01-06T16:45:06Z</updated>

		<summary type="html">&lt;p&gt;Jamesp1989: /* Ravenlord&amp;#039;s */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
===Slime===&lt;br /&gt;
Endgame [[Incursion]] armor for Melee and Magic classes.&lt;br /&gt;
{{ArmorSetTable|Slime Helmet/Slime Hat/Slime Chestplate/Slime Boots|total=90/82|setbonus=&#039;&#039;&#039;With Helmet:&#039;&#039;&#039;&amp;lt;br&amp;gt;+30 max resilience&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;With Hat:&#039;&#039;&#039;&amp;lt;br&amp;gt;+250/+475 max mana (+25 per tier)&amp;lt;br&amp;gt;+2 projectile bounces&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;With Any:&#039;&#039;&#039;&amp;lt;br&amp;gt;Press &#039;&#039;&#039;V&#039;&#039;&#039; to reduce all damage you&amp;lt;br&amp;gt;take to 1 for 5 seconds, but receive&amp;lt;br&amp;gt;considerably more knockback|images=[[File:Slime Armor Helmet Set.png]]&amp;lt;br&amp;gt;[[File:Slime Armor Hat Set.png]]}}&lt;br /&gt;
&lt;br /&gt;
===Nightsteel===&lt;br /&gt;
Endgame [[Incursion]] armor for all classes, higher defense but less offense for melee and mage classes compared to Slime Armor Set.&lt;br /&gt;
{{ArmorSetTable|Nightsteel Helmet/Nightsteel Mask/Nightsteel Veil/Nightsteel Circlet/Nightsteel Chestplate/Nightsteel Boots|total=90/84/82/77|setbonus=&#039;&#039;&#039;With Helmet:&#039;&#039;&#039;&amp;lt;br&amp;gt;+30 max resilience&amp;lt;br&amp;gt;+30% resilience gain&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;With Veil:&#039;&#039;&#039;&amp;lt;br&amp;gt;+250/+475 max mana (+25 per tier)&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;With Circlet:&#039;&#039;&#039;&amp;lt;br&amp;gt;+2 max summons&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;With Any:&#039;&#039;&#039;&amp;lt;br&amp;gt;Press &#039;&#039;&#039;V&#039;&#039;&#039; to get a boost and become&amp;lt;br&amp;gt;untargetable, but cannot attack&amp;lt;br&amp;gt;for 3 seconds|images=[[File:Nightsteel Armor Helmet Set.png]]&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;[[File:Nightsteel Armor Mask Set.png]]&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;[[File:Nightsteel Armor Veil Set.png]]&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;[[File:Nightsteel Armor Circlet Set.png]]}}&lt;br /&gt;
&lt;br /&gt;
===Spiderite===&lt;br /&gt;
Endgame [[Incursion]] armor for all classes.&lt;br /&gt;
{{ArmorSetTable|Spiderite Helmet/Spiderite Hood/Spiderite Hat/Spiderite Crown/Spiderite Chestplate/Spiderite Greaves|total=90/84/82/77|setbonus=&#039;&#039;&#039;With Helmet:&#039;&#039;&#039;&amp;lt;br&amp;gt;+20 max resilience&amp;lt;br&amp;gt;+50% resilience gain&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;With Hat:&#039;&#039;&#039;&amp;lt;br&amp;gt;+250/+475 max mana (+25 per tier)&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;With Crown:&#039;&#039;&#039;&amp;lt;br&amp;gt;+2 max summons&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;With Any:&#039;&#039;&#039;&amp;lt;br&amp;gt;Press &#039;&#039;&#039;V&#039;&#039;&#039; to manifest a line of toxic webs&amp;lt;br&amp;gt;for 10 seconds, 60 seconds cooldown&amp;lt;br&amp;gt;Grants immunity to slows|images=[[File:Spiderite Armor Helmet Set.png]]&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;[[File:Spiderite Armor Hood Set.png]]&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;[[File:Spiderite Armor Hat Set.png]]&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;[[File:Spiderite Armor Crown Set.png]]}}&lt;br /&gt;
&lt;br /&gt;
===Dusk===&lt;br /&gt;
Endgame [[Incursion]] armor for Magic and Summoner classes. Has the same base defense of its Dawn counterpart.&lt;br /&gt;
&lt;br /&gt;
Characters with a full set glow at night. &lt;br /&gt;
&lt;br /&gt;
{{ArmorSetTable|Dusk Helmet/Dusk Chestplate/Dusk Boots|total=90|setbonus=+400 max mana&amp;lt;br&amp;gt;Modifies Magic and Summon attacks during nighttime &#039;&#039;(19:00 to 7:00)&#039;&#039;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;Magic:&#039;&#039;&#039;&amp;lt;br&amp;gt;Shoots 5 homing Moonlit Bolts in random directions&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;Summon:&#039;&#039;&#039;&amp;lt;br&amp;gt;Summons 1 small Moon with each summoning that lasts for 5 seconds and flies&amp;lt;br&amp;gt;toward the target, dealing close-range damage &#039;&#039;(Maximum of 10 due to lifespan)&#039;&#039;|images=&#039;&#039;&#039;During Day&#039;&#039;&#039;&amp;lt;br&amp;gt;[[File:Dusk Armor Set.png|center]]&amp;lt;br&amp;gt;&#039;&#039;&#039;During Night&#039;&#039;&#039;&amp;lt;br&amp;gt;[[File:Dusk Armor Set Night.png|center]]}}&lt;br /&gt;
&lt;br /&gt;
===Dawn===&lt;br /&gt;
Endgame [[Incursion]] armor for Melee and Ranged classes. Has the same base defense of its Dusk counterpart.&lt;br /&gt;
{{ArmorSetTable|Dawn Helmet/Dawn Chestplate/Dawn Boots|total=90|setbonus=Modifies Melee and Ranged attacks during daytime &#039;&#039;(7:00 to 19:00)&#039;&#039;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;Melee:&#039;&#039;&#039;&amp;lt;br&amp;gt; Engulfs you in flames, exploding and applying Burning for 5 seconds&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;Ranged:&#039;&#039;&#039;&amp;lt;br&amp;gt;Shoots 2 Flame Orbs diagonally that pass through walls and applies burning for 10 seconds|images=&#039;&#039;&#039;During Day&#039;&#039;&#039;&amp;lt;br&amp;gt;[[File:Dawn Armor Set.png|center]]&amp;lt;br&amp;gt;&#039;&#039;&#039;During Night&#039;&#039;&#039;&amp;lt;br&amp;gt;[[File:Dawn Armor Set Night.png|center]]}}&lt;br /&gt;
&lt;br /&gt;
===Crystal===&lt;br /&gt;
Endgame [[Incursion]] armor for all classes.&lt;br /&gt;
{{ArmorSetTable|Amethyst Helmet/Sapphire Eyepatch/Emerald Mask/Ruby Crown/Crystal Chestplate/Crystal Boots|total=90|setbonus=&#039;&#039;&#039;With Helmet:&#039;&#039;&#039;&amp;lt;br&amp;gt;Deal 1% increased damage per 10 max resilience&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;With Eyepatch:&#039;&#039;&#039;&amp;lt;br&amp;gt;Press &#039;&#039;&#039;V&#039;&#039;&#039; to increase resilience regeneration&amp;lt;br&amp;gt;by 250% for 5 seconds, 45 seconds cooldown&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;With Mask:&#039;&#039;&#039;&amp;lt;br&amp;gt;You deal 50% more (magic) damage,&amp;lt;br&amp;gt;but take 25% more damage as well&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;With Crown:&#039;&#039;&#039;&amp;lt;br&amp;gt;Increase max summons by 1 per 150 max resilience|images=[[File:Crystal Armor Amethyst Set.png|center]]&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;[[File:Crystal Armor Sapphire Set.png|center]]&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;[[File:Crystal Armor Emerald Set.png|center]]&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;[[File:Crystal Armor Ruby Set.png|center]]}}&lt;br /&gt;
&lt;br /&gt;
===Battle Chef&#039;s===&lt;br /&gt;
{{ArmorSetTable|Battle Chef&#039;s Hat/Battle Chef&#039;s Chestplate/Battle Chef&#039;s Boots|total=90|setbonus=You can now be affected by one more food buff at the same time|images=.}}&lt;br /&gt;
&lt;br /&gt;
===Ravenlord&#039;s===&lt;br /&gt;
Endgame [[Incursion]] armor for all classes. Fastest movement speed.&lt;br /&gt;
{{ArmorSetTable|Ravenlord&#039;s Headdress/Ravenlord&#039;s Chestplate/Ravenlord&#039;s Boots|total=90|setbonus= Feathers spawn when moving, homing in on enemies&amp;lt;br&amp;gt;and dealing damage based on your movement speed|images=&#039;&#039;&#039;When Stationary:&#039;&#039;&#039;&amp;lt;br&amp;gt;[[File:Ravenlords Armor Set Stationary.png]]&amp;lt;br&amp;gt;&#039;&#039;&#039;When Moving:&#039;&#039;&#039;&amp;lt;br&amp;gt;[[File:Ravenlords Armor Set Moving.png]]}}&lt;br /&gt;
&lt;br /&gt;
===Arcanic===&lt;br /&gt;
Endgame Incursion armor for mages.&lt;br /&gt;
{{ArmorSetTable|Arcanic Helmet/Arcanic Chestplate/Arcanic Boots|total=90|setbonus=Press &#039;&#039;&#039;V&#039;&#039;&#039; to become Overcharged&amp;lt;br&amp;gt;While Overcharged, you drain 0.75% of your max mana every second, but also gain 2 stacks of Overcharged Mana for every point of mana lost&amp;lt;br&amp;gt;When you reach 20 stacks of Overcharged Mana, fire powerful lightning at nearby enemies}}&lt;/div&gt;</summary>
		<author><name>Jamesp1989</name></author>
	</entry>
	<entry>
		<id>https://necessewiki.com/mediawiki/index.php?title=User:Jamesp1989&amp;diff=24598</id>
		<title>User:Jamesp1989</title>
		<link rel="alternate" type="text/html" href="https://necessewiki.com/mediawiki/index.php?title=User:Jamesp1989&amp;diff=24598"/>
		<updated>2026-01-06T16:42:56Z</updated>

		<summary type="html">&lt;p&gt;Jamesp1989: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[{{FULLPAGENAME}}/LODRAFT]]&lt;br /&gt;
&lt;br /&gt;
{{#if:{{#invoke:NecesseRecipes|getRecipesOld|@armoritem@}}|{{#vardefine:$hasrecipes|1}}}}&lt;/div&gt;</summary>
		<author><name>Jamesp1989</name></author>
	</entry>
	<entry>
		<id>https://necessewiki.com/mediawiki/index.php?title=User:Jamesp1989&amp;diff=24597</id>
		<title>User:Jamesp1989</title>
		<link rel="alternate" type="text/html" href="https://necessewiki.com/mediawiki/index.php?title=User:Jamesp1989&amp;diff=24597"/>
		<updated>2026-01-06T16:39:50Z</updated>

		<summary type="html">&lt;p&gt;Jamesp1989: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[{{FULLPAGENAME}}/LODRAFT]]&lt;br /&gt;
{{#invoke:NecesseRecipes|getRecipesOld|&amp;quot;ravenlordsheaddress&amp;quot;}}&lt;/div&gt;</summary>
		<author><name>Jamesp1989</name></author>
	</entry>
	<entry>
		<id>https://necessewiki.com/mediawiki/index.php?title=User:Jamesp1989&amp;diff=24596</id>
		<title>User:Jamesp1989</title>
		<link rel="alternate" type="text/html" href="https://necessewiki.com/mediawiki/index.php?title=User:Jamesp1989&amp;diff=24596"/>
		<updated>2026-01-06T16:38:54Z</updated>

		<summary type="html">&lt;p&gt;Jamesp1989: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[{{FULLPAGENAME}}/LODRAFT]]&lt;br /&gt;
#invoke:NecesseRecipes|getRecipesOld|&amp;quot;Ravenlords Headdress&amp;quot;&lt;/div&gt;</summary>
		<author><name>Jamesp1989</name></author>
	</entry>
	<entry>
		<id>https://necessewiki.com/mediawiki/index.php?title=Incursion_tier_Armor&amp;diff=24593</id>
		<title>Incursion tier Armor</title>
		<link rel="alternate" type="text/html" href="https://necessewiki.com/mediawiki/index.php?title=Incursion_tier_Armor&amp;diff=24593"/>
		<updated>2026-01-02T20:55:14Z</updated>

		<summary type="html">&lt;p&gt;Jamesp1989: Created page with &amp;quot; ===Slime=== Endgame Incursion armor for Melee and Magic classes. {{ArmorSetTable|Slime Helmet/Slime Hat/Slime Chestplate/Slime Boots|total=90/82|setbonus=&amp;#039;&amp;#039;&amp;#039;With Helmet:&amp;#039;&amp;#039;&amp;#039;&amp;lt;br&amp;gt;+30 max resilience&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;#039;&amp;#039;&amp;#039;With Hat:&amp;#039;&amp;#039;&amp;#039;&amp;lt;br&amp;gt;+250/+475 max mana (+25 per tier)&amp;lt;br&amp;gt;+2 projectile bounces&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;#039;&amp;#039;&amp;#039;With Any:&amp;#039;&amp;#039;&amp;#039;&amp;lt;br&amp;gt;Press &amp;#039;&amp;#039;&amp;#039;V&amp;#039;&amp;#039;&amp;#039; to reduce all damage you&amp;lt;br&amp;gt;take to 1 for 5 seconds, but receive&amp;lt;br&amp;gt;considerably more knockback|images=File:Slime Armor Helmet Set.png&amp;lt;br&amp;gt;File:S...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
===Slime===&lt;br /&gt;
Endgame [[Incursion]] armor for Melee and Magic classes.&lt;br /&gt;
{{ArmorSetTable|Slime Helmet/Slime Hat/Slime Chestplate/Slime Boots|total=90/82|setbonus=&#039;&#039;&#039;With Helmet:&#039;&#039;&#039;&amp;lt;br&amp;gt;+30 max resilience&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;With Hat:&#039;&#039;&#039;&amp;lt;br&amp;gt;+250/+475 max mana (+25 per tier)&amp;lt;br&amp;gt;+2 projectile bounces&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;With Any:&#039;&#039;&#039;&amp;lt;br&amp;gt;Press &#039;&#039;&#039;V&#039;&#039;&#039; to reduce all damage you&amp;lt;br&amp;gt;take to 1 for 5 seconds, but receive&amp;lt;br&amp;gt;considerably more knockback|images=[[File:Slime Armor Helmet Set.png]]&amp;lt;br&amp;gt;[[File:Slime Armor Hat Set.png]]}}&lt;br /&gt;
&lt;br /&gt;
===Nightsteel===&lt;br /&gt;
Endgame [[Incursion]] armor for all classes, higher defense but less offense for melee and mage classes compared to Slime Armor Set.&lt;br /&gt;
{{ArmorSetTable|Nightsteel Helmet/Nightsteel Mask/Nightsteel Veil/Nightsteel Circlet/Nightsteel Chestplate/Nightsteel Boots|total=90/84/82/77|setbonus=&#039;&#039;&#039;With Helmet:&#039;&#039;&#039;&amp;lt;br&amp;gt;+30 max resilience&amp;lt;br&amp;gt;+30% resilience gain&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;With Veil:&#039;&#039;&#039;&amp;lt;br&amp;gt;+250/+475 max mana (+25 per tier)&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;With Circlet:&#039;&#039;&#039;&amp;lt;br&amp;gt;+2 max summons&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;With Any:&#039;&#039;&#039;&amp;lt;br&amp;gt;Press &#039;&#039;&#039;V&#039;&#039;&#039; to get a boost and become&amp;lt;br&amp;gt;untargetable, but cannot attack&amp;lt;br&amp;gt;for 3 seconds|images=[[File:Nightsteel Armor Helmet Set.png]]&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;[[File:Nightsteel Armor Mask Set.png]]&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;[[File:Nightsteel Armor Veil Set.png]]&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;[[File:Nightsteel Armor Circlet Set.png]]}}&lt;br /&gt;
&lt;br /&gt;
===Spiderite===&lt;br /&gt;
Endgame [[Incursion]] armor for all classes.&lt;br /&gt;
{{ArmorSetTable|Spiderite Helmet/Spiderite Hood/Spiderite Hat/Spiderite Crown/Spiderite Chestplate/Spiderite Greaves|total=90/84/82/77|setbonus=&#039;&#039;&#039;With Helmet:&#039;&#039;&#039;&amp;lt;br&amp;gt;+20 max resilience&amp;lt;br&amp;gt;+50% resilience gain&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;With Hat:&#039;&#039;&#039;&amp;lt;br&amp;gt;+250/+475 max mana (+25 per tier)&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;With Crown:&#039;&#039;&#039;&amp;lt;br&amp;gt;+2 max summons&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;With Any:&#039;&#039;&#039;&amp;lt;br&amp;gt;Press &#039;&#039;&#039;V&#039;&#039;&#039; to manifest a line of toxic webs&amp;lt;br&amp;gt;for 10 seconds, 60 seconds cooldown&amp;lt;br&amp;gt;Grants immunity to slows|images=[[File:Spiderite Armor Helmet Set.png]]&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;[[File:Spiderite Armor Hood Set.png]]&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;[[File:Spiderite Armor Hat Set.png]]&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;[[File:Spiderite Armor Crown Set.png]]}}&lt;br /&gt;
&lt;br /&gt;
===Dusk===&lt;br /&gt;
Endgame [[Incursion]] armor for Magic and Summoner classes. Has the same base defense of its Dawn counterpart.&lt;br /&gt;
&lt;br /&gt;
Characters with a full set glow at night. &lt;br /&gt;
&lt;br /&gt;
{{ArmorSetTable|Dusk Helmet/Dusk Chestplate/Dusk Boots|total=90|setbonus=+400 max mana&amp;lt;br&amp;gt;Modifies Magic and Summon attacks during nighttime &#039;&#039;(19:00 to 7:00)&#039;&#039;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;Magic:&#039;&#039;&#039;&amp;lt;br&amp;gt;Shoots 5 homing Moonlit Bolts in random directions&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;Summon:&#039;&#039;&#039;&amp;lt;br&amp;gt;Summons 1 small Moon with each summoning that lasts for 5 seconds and flies&amp;lt;br&amp;gt;toward the target, dealing close-range damage &#039;&#039;(Maximum of 10 due to lifespan)&#039;&#039;|images=&#039;&#039;&#039;During Day&#039;&#039;&#039;&amp;lt;br&amp;gt;[[File:Dusk Armor Set.png|center]]&amp;lt;br&amp;gt;&#039;&#039;&#039;During Night&#039;&#039;&#039;&amp;lt;br&amp;gt;[[File:Dusk Armor Set Night.png|center]]}}&lt;br /&gt;
&lt;br /&gt;
===Dawn===&lt;br /&gt;
Endgame [[Incursion]] armor for Melee and Ranged classes. Has the same base defense of its Dusk counterpart.&lt;br /&gt;
{{ArmorSetTable|Dawn Helmet/Dawn Chestplate/Dawn Boots|total=90|setbonus=Modifies Melee and Ranged attacks during daytime &#039;&#039;(7:00 to 19:00)&#039;&#039;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;Melee:&#039;&#039;&#039;&amp;lt;br&amp;gt; Engulfs you in flames, exploding and applying Burning for 5 seconds&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;Ranged:&#039;&#039;&#039;&amp;lt;br&amp;gt;Shoots 2 Flame Orbs diagonally that pass through walls and applies burning for 10 seconds|images=&#039;&#039;&#039;During Day&#039;&#039;&#039;&amp;lt;br&amp;gt;[[File:Dawn Armor Set.png|center]]&amp;lt;br&amp;gt;&#039;&#039;&#039;During Night&#039;&#039;&#039;&amp;lt;br&amp;gt;[[File:Dawn Armor Set Night.png|center]]}}&lt;br /&gt;
&lt;br /&gt;
===Crystal===&lt;br /&gt;
Endgame [[Incursion]] armor for all classes.&lt;br /&gt;
{{ArmorSetTable|Amethyst Helmet/Sapphire Eyepatch/Emerald Mask/Ruby Crown/Crystal Chestplate/Crystal Boots|total=90|setbonus=&#039;&#039;&#039;With Helmet:&#039;&#039;&#039;&amp;lt;br&amp;gt;Deal 1% increased damage per 10 max resilience&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;With Eyepatch:&#039;&#039;&#039;&amp;lt;br&amp;gt;Press &#039;&#039;&#039;V&#039;&#039;&#039; to increase resilience regeneration&amp;lt;br&amp;gt;by 250% for 5 seconds, 45 seconds cooldown&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;With Mask:&#039;&#039;&#039;&amp;lt;br&amp;gt;You deal 50% more (magic) damage,&amp;lt;br&amp;gt;but take 25% more damage as well&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;With Crown:&#039;&#039;&#039;&amp;lt;br&amp;gt;Increase max summons by 1 per 150 max resilience|images=[[File:Crystal Armor Amethyst Set.png|center]]&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;[[File:Crystal Armor Sapphire Set.png|center]]&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;[[File:Crystal Armor Emerald Set.png|center]]&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;[[File:Crystal Armor Ruby Set.png|center]]}}&lt;br /&gt;
&lt;br /&gt;
===Battle Chef&#039;s===&lt;br /&gt;
{{ArmorSetTable|Battle Chef&#039;s Hat/Battle Chef&#039;s Chestplate/Battle Chef&#039;s Boots|total=90|setbonus=You can now be affected by one more food buff at the same time|images=.}}&lt;br /&gt;
&lt;br /&gt;
===Ravenlord&#039;s===&lt;br /&gt;
Endgame [[Incursion]] armor for all classes. Fastest movement speed.&lt;br /&gt;
{{ArmorSetTable|Ravenlords Headdress/Ravenlords Chestplate/Ravenlords Boots|total=90|setbonus= Feathers spawn when moving, homing in on enemies&amp;lt;br&amp;gt;and dealing damage based on your movement speed|images=&#039;&#039;&#039;When Stationary:&#039;&#039;&#039;&amp;lt;br&amp;gt;[[File:Ravenlords Armor Set Stationary.png]]&amp;lt;br&amp;gt;&#039;&#039;&#039;When Moving:&#039;&#039;&#039;&amp;lt;br&amp;gt;[[File:Ravenlords Armor Set Moving.png]]}}&lt;br /&gt;
&lt;br /&gt;
===Arcanic===&lt;br /&gt;
Endgame Incursion armor for mages.&lt;br /&gt;
{{ArmorSetTable|Arcanic Helmet/Arcanic Chestplate/Arcanic Boots|total=90|setbonus=Press &#039;&#039;&#039;V&#039;&#039;&#039; to become Overcharged&amp;lt;br&amp;gt;While Overcharged, you drain 0.75% of your max mana every second, but also gain 2 stacks of Overcharged Mana for every point of mana lost&amp;lt;br&amp;gt;When you reach 20 stacks of Overcharged Mana, fire powerful lightning at nearby enemies}}&lt;/div&gt;</summary>
		<author><name>Jamesp1989</name></author>
	</entry>
	<entry>
		<id>https://necessewiki.com/mediawiki/index.php?title=Deep_Cave_tier_Armor&amp;diff=24592</id>
		<title>Deep Cave tier Armor</title>
		<link rel="alternate" type="text/html" href="https://necessewiki.com/mediawiki/index.php?title=Deep_Cave_tier_Armor&amp;diff=24592"/>
		<updated>2026-01-02T20:53:00Z</updated>

		<summary type="html">&lt;p&gt;Jamesp1989: Created page with &amp;quot; ===Tungsten=== {{ArmorSetTable|Tungsten Helmet/Tungsten Chestplate/Tungsten Boots|total=64|setbonus=+30 max resilience&amp;lt;br&amp;gt;Knockback resistance&amp;lt;br&amp;gt;50% increased knockback|images=File:Tungsten Armor Set.png}}  ===Shadow=== This armor is for the Ranger and Mage classes. {{ArmorSetTable|Shadow Hood/Shadow Hat/Shadow Mantle/Shadow Boots|total=46/42|setbonus=&amp;#039;&amp;#039;&amp;#039;With Hood:&amp;#039;&amp;#039;&amp;#039;&amp;lt;br&amp;gt;+5% crit chance&amp;lt;br&amp;gt;+10% movement speed&amp;lt;br&amp;gt;+15% projectile velocity&amp;lt;br&amp;gt;+10% damage while not mov...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
===Tungsten===&lt;br /&gt;
{{ArmorSetTable|Tungsten Helmet/Tungsten Chestplate/Tungsten Boots|total=64|setbonus=+30 max resilience&amp;lt;br&amp;gt;Knockback resistance&amp;lt;br&amp;gt;50% increased knockback|images=[[File:Tungsten Armor Set.png]]}}&lt;br /&gt;
&lt;br /&gt;
===Shadow===&lt;br /&gt;
This armor is for the Ranger and Mage classes.&lt;br /&gt;
{{ArmorSetTable|Shadow Hood/Shadow Hat/Shadow Mantle/Shadow Boots|total=46/42|setbonus=&#039;&#039;&#039;With Hood:&#039;&#039;&#039;&amp;lt;br&amp;gt;+5% crit chance&amp;lt;br&amp;gt;+10% movement speed&amp;lt;br&amp;gt;+15% projectile velocity&amp;lt;br&amp;gt;+10% damage while not moving&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;With Hat:&#039;&#039;&#039;&amp;lt;br&amp;gt;+5% movement speed&amp;lt;br&amp;gt;+15% projectile velocity&amp;lt;br&amp;gt;+200 max mana&amp;lt;br&amp;gt;Magic attacks haunt target for&amp;lt;br&amp;gt;25 damage over 5 seconds&amp;lt;br&amp;gt;|images=[[File:Shadow Hat Armor Set.png]]&amp;lt;br&amp;gt;[[File:Shadow Hood Armor Set.png]]}}&lt;br /&gt;
&lt;br /&gt;
===Soulseed===&lt;br /&gt;
{{ArmorSetTable|Soulseed Crown/Soulseed Chestplate/Soulseed Boots|total=40|setbonus=+1 max summon&amp;lt;br&amp;gt;Press &#039;&#039;&#039;V&#039;&#039;&#039; to explode all your active summons dealing massive damage&amp;lt;br&amp;gt;60 seconds cooldown|images=.}}&lt;br /&gt;
&lt;br /&gt;
===Glacial===&lt;br /&gt;
This armor is for Melee and Summoner class.&lt;br /&gt;
{{ArmorSetTable|Glacial Helmet/Glacial Circlet/Glacial Chestplate/Glacial Boots|total=64/44|setbonus=&#039;&#039;&#039;With Helmet:&#039;&#039;&#039;&amp;lt;br&amp;gt;+20 max resilience&amp;lt;br&amp;gt;+20% resilience gain&amp;lt;br&amp;gt;Melee attacks shoot out an icicle&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;With Circlet:&#039;&#039;&#039;&amp;lt;br&amp;gt;+1 max summons&amp;lt;br&amp;gt;Summon attacks slow target|images=[[File:Glacial Circlet Armor Set.png|center]]&amp;lt;br&amp;gt;[[File:Glacial Helmet Armor Set.png|center]]}}&lt;br /&gt;
&lt;br /&gt;
===Deepfrost===&lt;br /&gt;
{{ArmorSetTable|Deepfrost Hood/Deepfrost Chestplate/Deepfrost Boots|total=56|setbonus=An animated bow will follow you and fire projectiles&amp;lt;br&amp;gt;whenever you use a ranged weapon|images=.}}&lt;br /&gt;
&lt;br /&gt;
===Cryo Witch===&lt;br /&gt;
This armor is for Mage and Summoner class.&lt;br /&gt;
{{ArmorSetTable|Cryo Witch Hat/Cryo Witch Robe/Cryo Witch Shoes|total=52|setbonus=+200 max mana&amp;lt;br&amp;gt;Press &#039;&#039;&#039;V&#039;&#039;&#039; to encase yourself in ice while charging up a frost nova,&amp;lt;br&amp;gt;freezing all nonhuman mobs in a large area}}&lt;br /&gt;
&lt;br /&gt;
===Ninja===&lt;br /&gt;
{{ArmorSetTable|Ninja Hood/Ninja Robe/Ninja Shoes|total=50|setbonus=&#039;&#039;&#039;You&#039;re a freakin&#039; ninja!&#039;&#039;&#039;&amp;lt;br&amp;gt;Removes movement speed&amp;lt;br&amp;gt;reduction when attacking|obtained=Dropped from [[Ninja|Ninjas]]&amp;lt;br&amp;gt;in [[Caves#Deep Snow Caves|Deep Snow Caves]]|images=[[File:Ninja Armor Set.png|center]]}}&lt;br /&gt;
&lt;br /&gt;
===Dryad===&lt;br /&gt;
{{ArmorSetTable|Dryad Helmet/Dryad Scarf/Dryad Hat/Dryad Crown/Dryad Chestplate/Dryad Boots|total=70/60/54/50|setbonus=&#039;&#039;&#039;With Helmet:&#039;&#039;&#039;&amp;lt;br&amp;gt;20 max resilience&amp;lt;br&amp;gt;+20% resilience gain&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;With Scarf:&#039;&#039;&#039;&amp;lt;br&amp;gt;+10 armor penetration&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;With Hat:&#039;&#039;&#039;&amp;lt;br&amp;gt;+200 max mana&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;With Crown:&#039;&#039;&#039;&amp;lt;br&amp;gt;+1 max summons&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;With Any:&#039;&#039;&#039;&amp;lt;br&amp;gt;When out of combat, gain up to 3 Barkskin stacks which grants 10 armor each,&amp;lt;br&amp;gt;but lose 1 stack every time you&#039;re hit.}}&lt;br /&gt;
&lt;br /&gt;
===Mycelium===&lt;br /&gt;
This armor is for the Ranger and Summoner classes.&lt;br /&gt;
{{ArmorSetTable|Mycelium Hood/Mycelium Scarf/Mycelium Chestplate/Mycelium Boots|total=70/52|setbonus=&#039;&#039;&#039;With Hood:&#039;&#039;&#039; &amp;lt;br&amp;gt;Roots you to the ground and gives&amp;lt;br&amp;gt;+100% ranged attack speed&amp;lt;br&amp;gt;Drains stamina while holding action button&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;With Scarf:&#039;&#039;&#039;&amp;lt;br&amp;gt;+1 Max Summons&amp;lt;br&amp;gt;Each hit on enemies gives +0.5% movement speed for 4.5 seconds,&amp;lt;br&amp;gt;stacking up to 100 (50%)|images=[[File:Mycelium Hood Armor Set.png|center]]&amp;lt;br&amp;gt;[[File:Mycelium Scarf Armor Set.png|center]]}}&lt;br /&gt;
&lt;br /&gt;
===Widow===&lt;br /&gt;
This armor is for Mage class.&lt;br /&gt;
{{ArmorSetTable|Widow Helmet/Widow Chestplate/Widow Boots|total=62|setbonus=+250 max mana&amp;lt;br&amp;gt;Attacks poison target for&amp;lt;br&amp;gt;25 damage over 5 seconds&amp;lt;br&amp;gt;Grants immunity to slows|images=[[File:Widow Armor Set.png|center]]}}&lt;br /&gt;
&lt;br /&gt;
===Aged Champion===&lt;br /&gt;
This armor is for the melee class.&lt;br /&gt;
{{ArmorSetTable|Aged Champion Helmet/Aged Champion Chestplate/Aged Champion Greaves|total=74|setbonus=+30 max resilience&amp;lt;br&amp;gt;+20% resilience gain&amp;lt;br&amp;gt;Increases melee crit chance (+20%) and gives resilience regen (+1) when at full health&amp;lt;br&amp;gt;Blocking just before being hit greatly increases stamina regen (+200%)|images=}}&lt;br /&gt;
&lt;br /&gt;
===Ancient Fossil===&lt;br /&gt;
{{ArmorSetTable|Ancient Fossil Helmet/Ancient Fossil Mask/Ancient Fossil Chestplate/Ancient Fossil Boots|total=80/60|setbonus=&#039;&#039;&#039;With Helmet:&#039;&#039;&#039;&amp;lt;br&amp;gt;+10 max resilience&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;With Mask:&#039;&#039;&#039;&amp;lt;br&amp;gt;+1 max summons&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;With Any:&#039;&#039;&#039;&amp;lt;br&amp;gt;Press &#039;&#039;&#039;V&#039;&#039;&#039; to gain 100% crit chance for 5 seconds&amp;lt;br&amp;gt;60 seconds cooldown|images=[[File:Ancient Fossil Armor Set.png|center]]&amp;lt;br&amp;gt;[[File:Ancient Fossil Armor Mask Set.png|center]]}}&lt;br /&gt;
&lt;br /&gt;
===Sharpshooter===&lt;br /&gt;
{{ArmorSetTable|Sharpshooter Hat/Sharpshooter Coat/Sharpshooter Boots|total=74|setbonus=Ranged hits grants a stack of Bullseye&amp;lt;br&amp;gt;Bullseye guarantees ranged crits every 5 stacks}}&lt;br /&gt;
&lt;br /&gt;
===Ancestors===&lt;br /&gt;
{{ArmorSetTable|Ancestors Hat/Ancestors Robe/Ancestors Boots|total=62|setbonus=+ 275 Mana&amp;lt;br&amp;gt;Press &#039;&#039;&#039;V&#039;&#039;&#039; to manifest ghostly ancestors to fight by your side for 15 seconds&amp;lt;br&amp;gt;75 seconds cooldown after casting|images=.}}&lt;/div&gt;</summary>
		<author><name>Jamesp1989</name></author>
	</entry>
	<entry>
		<id>https://necessewiki.com/mediawiki/index.php?title=Cave_tier_Armor&amp;diff=24591</id>
		<title>Cave tier Armor</title>
		<link rel="alternate" type="text/html" href="https://necessewiki.com/mediawiki/index.php?title=Cave_tier_Armor&amp;diff=24591"/>
		<updated>2026-01-02T20:51:06Z</updated>

		<summary type="html">&lt;p&gt;Jamesp1989: Created page with &amp;quot;===Leather=== {{ArmorSetTable|Leather Hood/Leather Shirt/Leather Boots|total=4|setbonus=+10% attack speed|images=center}}  ===Cloth=== This armor is for Mage class. {{ArmorSetTable|Cloth Hat/Cloth Robe/Cloth Boots|total=4|setbonus=+15% magic damage&amp;lt;br&amp;gt;+30 max mana |images=center}}  ===Copper=== {{ArmorSetTable|Copper Helmet/Copper Chestplate/Copper Boots|total=5(7)|setbonus=+2 armor|images=File:Copper Armor Se...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Leather===&lt;br /&gt;
{{ArmorSetTable|Leather Hood/Leather Shirt/Leather Boots|total=4|setbonus=+10% attack speed|images=[[File:Leather Armor Set.png|center]]}}&lt;br /&gt;
&lt;br /&gt;
===Cloth===&lt;br /&gt;
This armor is for Mage class.&lt;br /&gt;
{{ArmorSetTable|Cloth Hat/Cloth Robe/Cloth Boots|total=4|setbonus=+15% magic damage&amp;lt;br&amp;gt;+30 max mana |images=[[File:Cloth Armor Set.png|center]]}}&lt;br /&gt;
&lt;br /&gt;
===Copper===&lt;br /&gt;
{{ArmorSetTable|Copper Helmet/Copper Chestplate/Copper Boots|total=5(7)|setbonus=+2 armor|images=[[File:Copper Armor Set.png|center]]}}&lt;br /&gt;
&lt;br /&gt;
===Iron===&lt;br /&gt;
{{ArmorSetTable|Iron Helmet/Iron Chestplate/Iron Boots|total=8(10)|setbonus=+2 armor|images=[[File:Iron Armor Set.png|center]]}}&lt;br /&gt;
&lt;br /&gt;
===Gold===&lt;br /&gt;
This set is for summoner classes (as long as you replace the gold helmet with a gold crown)&lt;br /&gt;
{{ArmorSetTable|Gold Helmet/Gold Crown/Gold Chestplate/Gold Boots|total=15/10|setbonus=&#039;&#039;&#039;With Helmet:&#039;&#039;&#039;&amp;lt;br&amp;gt;+2 armor&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;With Crown:&#039;&#039;&#039;&amp;lt;br&amp;gt;+1 max summons|images=[[File:Gold Armor Set.png|center]]&amp;lt;br&amp;gt;[[File:Crown Armor Set.png|center]]}}&lt;br /&gt;
&lt;br /&gt;
===Soldier&#039;s===&lt;br /&gt;
{{ArmorSetTable|Soldier&#039;s Helmet/Soldier&#039;s Cap/Soldier&#039;s Chestplate/Soldier&#039;s Boots|total=13/12|setbonus=&#039;&#039;&#039;With Helmet:&#039;&#039;&#039;&amp;lt;br&amp;gt;Gain a stacking frenzy buff when you kill an enemy&amp;lt;br&amp;gt;Frenzy increases attack speed and movement speed&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;With Cap:&#039;&#039;&#039;&amp;lt;br&amp;gt;Ranged weapon projectiles ricochet to other enemies on kill}}&lt;br /&gt;
&lt;br /&gt;
===Shark ===&lt;br /&gt;
{{ArmorSetTable|Shark Helmet/Shark Chestplate/Shark Boots|total=16|setbonus=Successful attacks bleed the target for 40 damage over 4 seconds&amp;lt;br&amp;gt;You gain temporary movement speed and damage for every enemy bled recently}}&lt;br /&gt;
&lt;br /&gt;
===Spider===&lt;br /&gt;
This armor is for Summoner class.&lt;br /&gt;
{{ArmorSetTable|Spider Helmet/Spider Chestplate/Spider Boots|total=6|setbonus=+1 max summons&amp;lt;br&amp;gt;Attacks poison target for&amp;lt;br&amp;gt;10 damage over 5 seconds&amp;lt;br&amp;gt;Grants immunity to slows|images=[[File:Spider Armor Set.png]]}}&lt;br /&gt;
&lt;br /&gt;
===Frost===&lt;br /&gt;
This armor is for Melee, Ranger and Mage classes.&lt;br /&gt;
{{ArmorSetTable|Frost Helmet/Frost Hood/Frost Hat/Frost Chestplate/Frost Boots|total=21/19/19|setbonus=&#039;&#039;&#039;With Helmet:&#039;&#039;&#039;&amp;lt;br&amp;gt;Melee attacks slows and&amp;lt;br&amp;gt;damages the target for 15&amp;lt;br&amp;gt;damage over 5 seconds&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;With Hood:&#039;&#039;&#039;&amp;lt;br&amp;gt;+10% crit chance&amp;lt;br&amp;gt;+15% projectile velocity&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;With Hat:&#039;&#039;&#039;&amp;lt;br&amp;gt;+10% magic crit chance&amp;lt;br&amp;gt;+60 max mana|images=[[File:Frost Armor Set.png|center]]&amp;lt;br&amp;gt;[[File:Frost Hood Armor Set.png|center]]&amp;lt;br&amp;gt;[[File:Frost Hat Armor Set.png|center]]}}&lt;br /&gt;
&lt;br /&gt;
===Demonic===&lt;br /&gt;
{{ArmorSetTable|Demonic Helmet/Demonic Chestplate/Demonic Boots|total=19|setbonus=Press action button to sacrifice 10% of your max health&amp;lt;br&amp;gt;Grants a buff of +15% damage +15% crit chance&amp;lt;br&amp;gt;and +15% movement speed for 8 seconds|images=[[File:Demonic Armor Set.png|center]]}}&lt;br /&gt;
&lt;br /&gt;
===Void===&lt;br /&gt;
This armor is for Mage and Summoner classes.&lt;br /&gt;
{{ArmorSetTable|Void Hat/Void Mask/Void Robe/Void Boots|total=19/15|setbonus=&#039;&#039;&#039;With Hat:&#039;&#039;&#039;&amp;lt;br&amp;gt;+100 max mana&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;With Mask:&#039;&#039;&#039;&amp;lt;br&amp;gt;+1 max summons&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;With Either:&#039;&#039;&#039; Press &#039;&#039;&#039;V&#039;&#039;&#039; to gain a burst of movement speed&amp;lt;br&amp;gt;30 second cooldown|images=[[File:Void Hat Armor Set.png]]&amp;lt;br&amp;gt;[[File:Void Mask Armor Set.png]]}}&lt;br /&gt;
&lt;br /&gt;
===Thief&#039;s===&lt;br /&gt;
{{ArmorSetTable|Thief&#039;s Cowl/Thiefs&#039;s Cloak/Thief&#039;s Boots|total=18|setbonus=You have a chance to steal coins from enemies on hit&amp;lt;br&amp;gt;Press &#039;&#039;&#039;V&#039;&#039;&#039; to throw a handful of coins at enemies&amp;lt;br&amp;gt;25 coins thrown, 15 seconds cooldown|images=.}}&lt;br /&gt;
&lt;br /&gt;
===Bloodplate===&lt;br /&gt;
An early game armor set for all classes based around health regen.&lt;br /&gt;
{{ArmorSetTable|Bloodplate Cowl/Bloodplate Chestplate/Bloodplate Boots|total=19|setbonus=After taking damage, your health&amp;lt;br&amp;gt;regen is doubled for 4 seconds|obtained=Can be found in [[Stone Coffin]]s in [[Mini_Biomes#Vampire_Crypt|Vampire Crypts]]&amp;lt;br&amp;gt;([[Caves#Forest Caves|Forest Caves]] and [[Snow#Snow Caves|Snow Caves]] biomes).|images=[[File:Bloodplate Armor Set.png|center]]}}&lt;br /&gt;
&lt;br /&gt;
===Arachnid===&lt;br /&gt;
This armor is for Summoner class.&lt;br /&gt;
{{ArmorSetTable|Arachnid Helmet/Arachnid Chestplate/Arachnid Legs|total=12|setbonus=+1 max summons&amp;lt;br&amp;gt;Spawns an additional spider summon for every third summon slot used|images=[[File:Arachnid Armor Set.png]]}}&lt;br /&gt;
&lt;br /&gt;
===Runic===&lt;br /&gt;
This armor is for Melee, Ranger, Mage, and Summoner classes.&lt;br /&gt;
{{ArmorSetTable|Runic Helmet/Runic Hood/Runic Hat/Runic Crown/Runic Chestplate/Runic Boots|total=28/28/26/19|setbonus=&#039;&#039;&#039;With Helmet, Hood, or Crown:&#039;&#039;&#039;&amp;lt;br&amp;gt;+100% mana regen&amp;lt;br&amp;gt;+10% attack speed&amp;lt;br&amp;gt;Press &#039;&#039;&#039;V&#039;&#039;&#039; to rapidly gain damage output while mana drains&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;With Hat:&#039;&#039;&#039;&amp;lt;br&amp;gt;+100 max mana&amp;lt;br&amp;gt;+50% life essence gain chance&amp;lt;br&amp;gt;Press &#039;&#039;&#039;V&#039;&#039;&#039; to gain 3 life essence orbs&amp;lt;br&amp;gt;60 second cooldown}}&lt;br /&gt;
&lt;br /&gt;
===Pharaoh&#039;s===&lt;br /&gt;
This armor is for Mage class.&lt;br /&gt;
{{ArmorSetTable|Pharaoh&#039;s Headdress/Pharaoh&#039;s Robe/Pharaoh&#039;s Sandals|total=34|setbonus=Periodically spawn locusts that explode on impact with enemies&amp;lt;br&amp;gt;Spending 75 mana will also cause a locust to spawn}}&lt;br /&gt;
&lt;br /&gt;
===Ivy===&lt;br /&gt;
This armor is for Melee, Ranger, Mage, and Summoner classes.&lt;br /&gt;
{{ArmorSetTable|Ivy Helmet/Ivy Hood/Ivy Hat/Ivy Circlet/Ivy Chestplate/Ivy Boots|total=41/36/35/27|setbonus=&#039;&#039;&#039;With Helmet:&#039;&#039;&#039;&amp;lt;br&amp;gt;+20 max resilience&amp;lt;br&amp;gt;Being hit drops a poisonous goo&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;With Hood:&#039;&#039;&#039;&amp;lt;br&amp;gt;Attacks poison target for&amp;lt;br&amp;gt;15 damage over 5 seconds&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;With Hat:&#039;&#039;&#039;&amp;lt;br&amp;gt;+150 max mana&amp;lt;br&amp;gt;Attacks poison target for 15 damage over 5 seconds&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;With Circlet:&#039;&#039;&#039;&amp;lt;br&amp;gt;+1 max summons&amp;lt;br&amp;gt;While in combat, occasionally&amp;lt;br&amp;gt;spawn a poison slime|images=[[File:Ivy Helmet Armor Set.png|center]]&amp;lt;br&amp;gt;[[File:Ivy Hood Armor Set.png|center]]&amp;lt;br&amp;gt;[[File:Ivy Hat Armor Set.png|center]]&amp;lt;br&amp;gt;[[File:Ivy Circlet Armor Set.png|center]]}}&lt;br /&gt;
&lt;br /&gt;
===Quartz===&lt;br /&gt;
{{ArmorSetTable|Quartz Helmet/Quartz Crown/Quartz Chestplate/Quartz Boots|total=48/34|setbonus=&#039;&#039;&#039;With Helmet:&#039;&#039;&#039;&amp;lt;br&amp;gt;+10 max resilience&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;With Crown:&#039;&#039;&#039;&amp;lt;br&amp;gt;+1 max summons&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;With Any:&#039;&#039;&#039;&amp;lt;br&amp;gt;Get a burst of movement&amp;lt;br&amp;gt;speed after being hit&amp;lt;br&amp;gt;10 seconds cooldown&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;|images=[[File:Quartz Helmet Armor Set.png|center]]&amp;lt;br&amp;gt;[[File:Quartz Crown Armor Set.png|center]]}}&lt;br /&gt;
&lt;br /&gt;
===Gunslinger===&lt;br /&gt;
{{ArmorSetTable|Gunslinger Hat/Gunslinger Vest/Gunslinger Boots|total=43|setbonus=Press &#039;&#039;&#039;V&#039;&#039;&#039; to rapidly shoot 6 bullets at surrounding enemies}}&lt;br /&gt;
&lt;br /&gt;
===Witch===&lt;br /&gt;
Dropped from Evil Witch and sold by Friendly Witch after defeating an Evil Witch.&lt;br /&gt;
{{ArmorSetTable|Witch Hat/Witch Robe/Witch Shoes|total=36|setbonus=+150 max mana&amp;lt;br&amp;gt;Being hit sometimes slows the attacker and spawns a charging baby crawling zombie}}&lt;br /&gt;
&lt;br /&gt;
{{Collapse bottom}}&lt;/div&gt;</summary>
		<author><name>Jamesp1989</name></author>
	</entry>
	<entry>
		<id>https://necessewiki.com/mediawiki/index.php?title=Armor&amp;diff=24590</id>
		<title>Armor</title>
		<link rel="alternate" type="text/html" href="https://necessewiki.com/mediawiki/index.php?title=Armor&amp;diff=24590"/>
		<updated>2026-01-02T20:49:33Z</updated>

		<summary type="html">&lt;p&gt;Jamesp1989: preparation for splitting up the armor pages&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Armor&#039;&#039;&#039; can be equipped by the player, [[Settlers]], and [[Raiders]]. Equipping armor reduces the damage taken from hits. Each point of armor reduces damage taken by 0.5 health.&lt;br /&gt;
&lt;br /&gt;
Equipping a full set of matching armor will give a &#039;set bonus&#039;.&lt;br /&gt;
&lt;br /&gt;
Armor pieces must be equipped in the armor slots to get their benefits, equipping them in the cosmetic slots does not provide any defense.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&#039;&#039;&#039;Note :&#039;&#039;&#039; Once the player unlocks [[Incursions]], all armor pieces can be upgraded at an [[Upgrade Station]] to reach a similar level of defenses and stat bonuses. Meaning that, without considering the unique set bonus, even a weak early game armor can be relevant for end game content. &amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== [[Cave tier Armor]] ==&lt;br /&gt;
{{Collapse top}}&lt;br /&gt;
&lt;br /&gt;
===Leather===&lt;br /&gt;
{{ArmorSetTable|Leather Hood/Leather Shirt/Leather Boots|total=4|setbonus=+10% attack speed|images=[[File:Leather Armor Set.png|center]]}}&lt;br /&gt;
&lt;br /&gt;
===Cloth===&lt;br /&gt;
This armor is for Mage class.&lt;br /&gt;
{{ArmorSetTable|Cloth Hat/Cloth Robe/Cloth Boots|total=4|setbonus=+15% magic damage&amp;lt;br&amp;gt;+30 max mana |images=[[File:Cloth Armor Set.png|center]]}}&lt;br /&gt;
&lt;br /&gt;
===Copper===&lt;br /&gt;
{{ArmorSetTable|Copper Helmet/Copper Chestplate/Copper Boots|total=5(7)|setbonus=+2 armor|images=[[File:Copper Armor Set.png|center]]}}&lt;br /&gt;
&lt;br /&gt;
===Iron===&lt;br /&gt;
{{ArmorSetTable|Iron Helmet/Iron Chestplate/Iron Boots|total=8(10)|setbonus=+2 armor|images=[[File:Iron Armor Set.png|center]]}}&lt;br /&gt;
&lt;br /&gt;
===Gold===&lt;br /&gt;
This set is for summoner classes (as long as you replace the gold helmet with a gold crown)&lt;br /&gt;
{{ArmorSetTable|Gold Helmet/Gold Crown/Gold Chestplate/Gold Boots|total=15/10|setbonus=&#039;&#039;&#039;With Helmet:&#039;&#039;&#039;&amp;lt;br&amp;gt;+2 armor&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;With Crown:&#039;&#039;&#039;&amp;lt;br&amp;gt;+1 max summons|images=[[File:Gold Armor Set.png|center]]&amp;lt;br&amp;gt;[[File:Crown Armor Set.png|center]]}}&lt;br /&gt;
&lt;br /&gt;
===Soldier&#039;s===&lt;br /&gt;
{{ArmorSetTable|Soldier&#039;s Helmet/Soldier&#039;s Cap/Soldier&#039;s Chestplate/Soldier&#039;s Boots|total=13/12|setbonus=&#039;&#039;&#039;With Helmet:&#039;&#039;&#039;&amp;lt;br&amp;gt;Gain a stacking frenzy buff when you kill an enemy&amp;lt;br&amp;gt;Frenzy increases attack speed and movement speed&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;With Cap:&#039;&#039;&#039;&amp;lt;br&amp;gt;Ranged weapon projectiles ricochet to other enemies on kill}}&lt;br /&gt;
&lt;br /&gt;
===Shark ===&lt;br /&gt;
{{ArmorSetTable|Shark Helmet/Shark Chestplate/Shark Boots|total=16|setbonus=Successful attacks bleed the target for 40 damage over 4 seconds&amp;lt;br&amp;gt;You gain temporary movement speed and damage for every enemy bled recently}}&lt;br /&gt;
&lt;br /&gt;
===Spider===&lt;br /&gt;
This armor is for Summoner class.&lt;br /&gt;
{{ArmorSetTable|Spider Helmet/Spider Chestplate/Spider Boots|total=6|setbonus=+1 max summons&amp;lt;br&amp;gt;Attacks poison target for&amp;lt;br&amp;gt;10 damage over 5 seconds&amp;lt;br&amp;gt;Grants immunity to slows|images=[[File:Spider Armor Set.png]]}}&lt;br /&gt;
&lt;br /&gt;
===Frost===&lt;br /&gt;
This armor is for Melee, Ranger and Mage classes.&lt;br /&gt;
{{ArmorSetTable|Frost Helmet/Frost Hood/Frost Hat/Frost Chestplate/Frost Boots|total=21/19/19|setbonus=&#039;&#039;&#039;With Helmet:&#039;&#039;&#039;&amp;lt;br&amp;gt;Melee attacks slows and&amp;lt;br&amp;gt;damages the target for 15&amp;lt;br&amp;gt;damage over 5 seconds&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;With Hood:&#039;&#039;&#039;&amp;lt;br&amp;gt;+10% crit chance&amp;lt;br&amp;gt;+15% projectile velocity&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;With Hat:&#039;&#039;&#039;&amp;lt;br&amp;gt;+10% magic crit chance&amp;lt;br&amp;gt;+60 max mana|images=[[File:Frost Armor Set.png|center]]&amp;lt;br&amp;gt;[[File:Frost Hood Armor Set.png|center]]&amp;lt;br&amp;gt;[[File:Frost Hat Armor Set.png|center]]}}&lt;br /&gt;
&lt;br /&gt;
===Demonic===&lt;br /&gt;
{{ArmorSetTable|Demonic Helmet/Demonic Chestplate/Demonic Boots|total=19|setbonus=Press action button to sacrifice 10% of your max health&amp;lt;br&amp;gt;Grants a buff of +15% damage +15% crit chance&amp;lt;br&amp;gt;and +15% movement speed for 8 seconds|images=[[File:Demonic Armor Set.png|center]]}}&lt;br /&gt;
&lt;br /&gt;
===Void===&lt;br /&gt;
This armor is for Mage and Summoner classes.&lt;br /&gt;
{{ArmorSetTable|Void Hat/Void Mask/Void Robe/Void Boots|total=19/15|setbonus=&#039;&#039;&#039;With Hat:&#039;&#039;&#039;&amp;lt;br&amp;gt;+100 max mana&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;With Mask:&#039;&#039;&#039;&amp;lt;br&amp;gt;+1 max summons&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;With Either:&#039;&#039;&#039; Press &#039;&#039;&#039;V&#039;&#039;&#039; to gain a burst of movement speed&amp;lt;br&amp;gt;30 second cooldown|images=[[File:Void Hat Armor Set.png]]&amp;lt;br&amp;gt;[[File:Void Mask Armor Set.png]]}}&lt;br /&gt;
&lt;br /&gt;
===Thief&#039;s===&lt;br /&gt;
{{ArmorSetTable|Thief&#039;s Cowl/Thiefs&#039;s Cloak/Thief&#039;s Boots|total=18|setbonus=You have a chance to steal coins from enemies on hit&amp;lt;br&amp;gt;Press &#039;&#039;&#039;V&#039;&#039;&#039; to throw a handful of coins at enemies&amp;lt;br&amp;gt;25 coins thrown, 15 seconds cooldown|images=.}}&lt;br /&gt;
&lt;br /&gt;
===Bloodplate===&lt;br /&gt;
An early game armor set for all classes based around health regen.&lt;br /&gt;
{{ArmorSetTable|Bloodplate Cowl/Bloodplate Chestplate/Bloodplate Boots|total=19|setbonus=After taking damage, your health&amp;lt;br&amp;gt;regen is doubled for 4 seconds|obtained=Can be found in [[Stone Coffin]]s in [[Mini_Biomes#Vampire_Crypt|Vampire Crypts]]&amp;lt;br&amp;gt;([[Caves#Forest Caves|Forest Caves]] and [[Snow#Snow Caves|Snow Caves]] biomes).|images=[[File:Bloodplate Armor Set.png|center]]}}&lt;br /&gt;
&lt;br /&gt;
===Arachnid===&lt;br /&gt;
This armor is for Summoner class.&lt;br /&gt;
{{ArmorSetTable|Arachnid Helmet/Arachnid Chestplate/Arachnid Legs|total=12|setbonus=+1 max summons&amp;lt;br&amp;gt;Spawns an additional spider summon for every third summon slot used|images=[[File:Arachnid Armor Set.png]]}}&lt;br /&gt;
&lt;br /&gt;
===Runic===&lt;br /&gt;
This armor is for Melee, Ranger, Mage, and Summoner classes.&lt;br /&gt;
{{ArmorSetTable|Runic Helmet/Runic Hood/Runic Hat/Runic Crown/Runic Chestplate/Runic Boots|total=28/28/26/19|setbonus=&#039;&#039;&#039;With Helmet, Hood, or Crown:&#039;&#039;&#039;&amp;lt;br&amp;gt;+100% mana regen&amp;lt;br&amp;gt;+10% attack speed&amp;lt;br&amp;gt;Press &#039;&#039;&#039;V&#039;&#039;&#039; to rapidly gain damage output while mana drains&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;With Hat:&#039;&#039;&#039;&amp;lt;br&amp;gt;+100 max mana&amp;lt;br&amp;gt;+50% life essence gain chance&amp;lt;br&amp;gt;Press &#039;&#039;&#039;V&#039;&#039;&#039; to gain 3 life essence orbs&amp;lt;br&amp;gt;60 second cooldown}}&lt;br /&gt;
&lt;br /&gt;
===Pharaoh&#039;s===&lt;br /&gt;
This armor is for Mage class.&lt;br /&gt;
{{ArmorSetTable|Pharaoh&#039;s Headdress/Pharaoh&#039;s Robe/Pharaoh&#039;s Sandals|total=34|setbonus=Periodically spawn locusts that explode on impact with enemies&amp;lt;br&amp;gt;Spending 75 mana will also cause a locust to spawn}}&lt;br /&gt;
&lt;br /&gt;
===Ivy===&lt;br /&gt;
This armor is for Melee, Ranger, Mage, and Summoner classes.&lt;br /&gt;
{{ArmorSetTable|Ivy Helmet/Ivy Hood/Ivy Hat/Ivy Circlet/Ivy Chestplate/Ivy Boots|total=41/36/35/27|setbonus=&#039;&#039;&#039;With Helmet:&#039;&#039;&#039;&amp;lt;br&amp;gt;+20 max resilience&amp;lt;br&amp;gt;Being hit drops a poisonous goo&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;With Hood:&#039;&#039;&#039;&amp;lt;br&amp;gt;Attacks poison target for&amp;lt;br&amp;gt;15 damage over 5 seconds&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;With Hat:&#039;&#039;&#039;&amp;lt;br&amp;gt;+150 max mana&amp;lt;br&amp;gt;Attacks poison target for 15 damage over 5 seconds&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;With Circlet:&#039;&#039;&#039;&amp;lt;br&amp;gt;+1 max summons&amp;lt;br&amp;gt;While in combat, occasionally&amp;lt;br&amp;gt;spawn a poison slime|images=[[File:Ivy Helmet Armor Set.png|center]]&amp;lt;br&amp;gt;[[File:Ivy Hood Armor Set.png|center]]&amp;lt;br&amp;gt;[[File:Ivy Hat Armor Set.png|center]]&amp;lt;br&amp;gt;[[File:Ivy Circlet Armor Set.png|center]]}}&lt;br /&gt;
&lt;br /&gt;
===Quartz===&lt;br /&gt;
{{ArmorSetTable|Quartz Helmet/Quartz Crown/Quartz Chestplate/Quartz Boots|total=48/34|setbonus=&#039;&#039;&#039;With Helmet:&#039;&#039;&#039;&amp;lt;br&amp;gt;+10 max resilience&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;With Crown:&#039;&#039;&#039;&amp;lt;br&amp;gt;+1 max summons&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;With Any:&#039;&#039;&#039;&amp;lt;br&amp;gt;Get a burst of movement&amp;lt;br&amp;gt;speed after being hit&amp;lt;br&amp;gt;10 seconds cooldown&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;|images=[[File:Quartz Helmet Armor Set.png|center]]&amp;lt;br&amp;gt;[[File:Quartz Crown Armor Set.png|center]]}}&lt;br /&gt;
&lt;br /&gt;
===Gunslinger===&lt;br /&gt;
{{ArmorSetTable|Gunslinger Hat/Gunslinger Vest/Gunslinger Boots|total=43|setbonus=Press &#039;&#039;&#039;V&#039;&#039;&#039; to rapidly shoot 6 bullets at surrounding enemies}}&lt;br /&gt;
&lt;br /&gt;
===Witch===&lt;br /&gt;
Dropped from Evil Witch and sold by Friendly Witch after defeating an Evil Witch.&lt;br /&gt;
{{ArmorSetTable|Witch Hat/Witch Robe/Witch Shoes|total=36|setbonus=+150 max mana&amp;lt;br&amp;gt;Being hit sometimes slows the attacker and spawns a charging baby crawling zombie}}&lt;br /&gt;
&lt;br /&gt;
{{Collapse bottom}}&lt;br /&gt;
&lt;br /&gt;
== [[Deep Cave tier Armor]] ==&lt;br /&gt;
{{Collapse top}}&lt;br /&gt;
&lt;br /&gt;
===Tungsten===&lt;br /&gt;
{{ArmorSetTable|Tungsten Helmet/Tungsten Chestplate/Tungsten Boots|total=64|setbonus=+30 max resilience&amp;lt;br&amp;gt;Knockback resistance&amp;lt;br&amp;gt;50% increased knockback|images=[[File:Tungsten Armor Set.png]]}}&lt;br /&gt;
&lt;br /&gt;
===Shadow===&lt;br /&gt;
This armor is for the Ranger and Mage classes.&lt;br /&gt;
{{ArmorSetTable|Shadow Hood/Shadow Hat/Shadow Mantle/Shadow Boots|total=46/42|setbonus=&#039;&#039;&#039;With Hood:&#039;&#039;&#039;&amp;lt;br&amp;gt;+5% crit chance&amp;lt;br&amp;gt;+10% movement speed&amp;lt;br&amp;gt;+15% projectile velocity&amp;lt;br&amp;gt;+10% damage while not moving&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;With Hat:&#039;&#039;&#039;&amp;lt;br&amp;gt;+5% movement speed&amp;lt;br&amp;gt;+15% projectile velocity&amp;lt;br&amp;gt;+200 max mana&amp;lt;br&amp;gt;Magic attacks haunt target for&amp;lt;br&amp;gt;25 damage over 5 seconds&amp;lt;br&amp;gt;|images=[[File:Shadow Hat Armor Set.png]]&amp;lt;br&amp;gt;[[File:Shadow Hood Armor Set.png]]}}&lt;br /&gt;
&lt;br /&gt;
===Soulseed===&lt;br /&gt;
{{ArmorSetTable|Soulseed Crown/Soulseed Chestplate/Soulseed Boots|total=40|setbonus=+1 max summon&amp;lt;br&amp;gt;Press &#039;&#039;&#039;V&#039;&#039;&#039; to explode all your active summons dealing massive damage&amp;lt;br&amp;gt;60 seconds cooldown|images=.}}&lt;br /&gt;
&lt;br /&gt;
===Glacial===&lt;br /&gt;
This armor is for Melee and Summoner class.&lt;br /&gt;
{{ArmorSetTable|Glacial Helmet/Glacial Circlet/Glacial Chestplate/Glacial Boots|total=64/44|setbonus=&#039;&#039;&#039;With Helmet:&#039;&#039;&#039;&amp;lt;br&amp;gt;+20 max resilience&amp;lt;br&amp;gt;+20% resilience gain&amp;lt;br&amp;gt;Melee attacks shoot out an icicle&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;With Circlet:&#039;&#039;&#039;&amp;lt;br&amp;gt;+1 max summons&amp;lt;br&amp;gt;Summon attacks slow target|images=[[File:Glacial Circlet Armor Set.png|center]]&amp;lt;br&amp;gt;[[File:Glacial Helmet Armor Set.png|center]]}}&lt;br /&gt;
&lt;br /&gt;
===Deepfrost===&lt;br /&gt;
{{ArmorSetTable|Deepfrost Hood/Deepfrost Chestplate/Deepfrost Boots|total=56|setbonus=An animated bow will follow you and fire projectiles&amp;lt;br&amp;gt;whenever you use a ranged weapon|images=.}}&lt;br /&gt;
&lt;br /&gt;
===Cryo Witch===&lt;br /&gt;
This armor is for Mage and Summoner class.&lt;br /&gt;
{{ArmorSetTable|Cryo Witch Hat/Cryo Witch Robe/Cryo Witch Shoes|total=52|setbonus=+200 max mana&amp;lt;br&amp;gt;Press &#039;&#039;&#039;V&#039;&#039;&#039; to encase yourself in ice while charging up a frost nova,&amp;lt;br&amp;gt;freezing all nonhuman mobs in a large area}}&lt;br /&gt;
&lt;br /&gt;
===Ninja===&lt;br /&gt;
{{ArmorSetTable|Ninja Hood/Ninja Robe/Ninja Shoes|total=50|setbonus=&#039;&#039;&#039;You&#039;re a freakin&#039; ninja!&#039;&#039;&#039;&amp;lt;br&amp;gt;Removes movement speed&amp;lt;br&amp;gt;reduction when attacking|obtained=Dropped from [[Ninja|Ninjas]]&amp;lt;br&amp;gt;in [[Caves#Deep Snow Caves|Deep Snow Caves]]|images=[[File:Ninja Armor Set.png|center]]}}&lt;br /&gt;
&lt;br /&gt;
===Dryad===&lt;br /&gt;
{{ArmorSetTable|Dryad Helmet/Dryad Scarf/Dryad Hat/Dryad Crown/Dryad Chestplate/Dryad Boots|total=70/60/54/50|setbonus=&#039;&#039;&#039;With Helmet:&#039;&#039;&#039;&amp;lt;br&amp;gt;20 max resilience&amp;lt;br&amp;gt;+20% resilience gain&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;With Scarf:&#039;&#039;&#039;&amp;lt;br&amp;gt;+10 armor penetration&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;With Hat:&#039;&#039;&#039;&amp;lt;br&amp;gt;+200 max mana&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;With Crown:&#039;&#039;&#039;&amp;lt;br&amp;gt;+1 max summons&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;With Any:&#039;&#039;&#039;&amp;lt;br&amp;gt;When out of combat, gain up to 3 Barkskin stacks which grants 10 armor each,&amp;lt;br&amp;gt;but lose 1 stack every time you&#039;re hit.}}&lt;br /&gt;
&lt;br /&gt;
===Mycelium===&lt;br /&gt;
This armor is for the Ranger and Summoner classes.&lt;br /&gt;
{{ArmorSetTable|Mycelium Hood/Mycelium Scarf/Mycelium Chestplate/Mycelium Boots|total=70/52|setbonus=&#039;&#039;&#039;With Hood:&#039;&#039;&#039; &amp;lt;br&amp;gt;Roots you to the ground and gives&amp;lt;br&amp;gt;+100% ranged attack speed&amp;lt;br&amp;gt;Drains stamina while holding action button&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;With Scarf:&#039;&#039;&#039;&amp;lt;br&amp;gt;+1 Max Summons&amp;lt;br&amp;gt;Each hit on enemies gives +0.5% movement speed for 4.5 seconds,&amp;lt;br&amp;gt;stacking up to 100 (50%)|images=[[File:Mycelium Hood Armor Set.png|center]]&amp;lt;br&amp;gt;[[File:Mycelium Scarf Armor Set.png|center]]}}&lt;br /&gt;
&lt;br /&gt;
===Widow===&lt;br /&gt;
This armor is for Mage class.&lt;br /&gt;
{{ArmorSetTable|Widow Helmet/Widow Chestplate/Widow Boots|total=62|setbonus=+250 max mana&amp;lt;br&amp;gt;Attacks poison target for&amp;lt;br&amp;gt;25 damage over 5 seconds&amp;lt;br&amp;gt;Grants immunity to slows|images=[[File:Widow Armor Set.png|center]]}}&lt;br /&gt;
&lt;br /&gt;
===Aged Champion===&lt;br /&gt;
This armor is for the melee class.&lt;br /&gt;
{{ArmorSetTable|Aged Champion Helmet/Aged Champion Chestplate/Aged Champion Greaves|total=74|setbonus=+30 max resilience&amp;lt;br&amp;gt;+20% resilience gain&amp;lt;br&amp;gt;Increases melee crit chance (+20%) and gives resilience regen (+1) when at full health&amp;lt;br&amp;gt;Blocking just before being hit greatly increases stamina regen (+200%)|images=}}&lt;br /&gt;
&lt;br /&gt;
===Ancient Fossil===&lt;br /&gt;
{{ArmorSetTable|Ancient Fossil Helmet/Ancient Fossil Mask/Ancient Fossil Chestplate/Ancient Fossil Boots|total=80/60|setbonus=&#039;&#039;&#039;With Helmet:&#039;&#039;&#039;&amp;lt;br&amp;gt;+10 max resilience&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;With Mask:&#039;&#039;&#039;&amp;lt;br&amp;gt;+1 max summons&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;With Any:&#039;&#039;&#039;&amp;lt;br&amp;gt;Press &#039;&#039;&#039;V&#039;&#039;&#039; to gain 100% crit chance for 5 seconds&amp;lt;br&amp;gt;60 seconds cooldown|images=[[File:Ancient Fossil Armor Set.png|center]]&amp;lt;br&amp;gt;[[File:Ancient Fossil Armor Mask Set.png|center]]}}&lt;br /&gt;
&lt;br /&gt;
===Sharpshooter===&lt;br /&gt;
{{ArmorSetTable|Sharpshooter Hat/Sharpshooter Coat/Sharpshooter Boots|total=74|setbonus=Ranged hits grants a stack of Bullseye&amp;lt;br&amp;gt;Bullseye guarantees ranged crits every 5 stacks}}&lt;br /&gt;
&lt;br /&gt;
===Ancestors===&lt;br /&gt;
{{ArmorSetTable|Ancestors Hat/Ancestors Robe/Ancestors Boots|total=62|setbonus=+ 275 Mana&amp;lt;br&amp;gt;Press &#039;&#039;&#039;V&#039;&#039;&#039; to manifest ghostly ancestors to fight by your side for 15 seconds&amp;lt;br&amp;gt;75 seconds cooldown after casting|images=.}}&lt;br /&gt;
&lt;br /&gt;
{{Collapse bottom}}&lt;br /&gt;
&lt;br /&gt;
== [[Incursion tier Armor]] ==&lt;br /&gt;
{{Collapse top}}&lt;br /&gt;
&lt;br /&gt;
===Slime===&lt;br /&gt;
Endgame [[Incursion]] armor for Melee and Magic classes.&lt;br /&gt;
{{ArmorSetTable|Slime Helmet/Slime Hat/Slime Chestplate/Slime Boots|total=90/82|setbonus=&#039;&#039;&#039;With Helmet:&#039;&#039;&#039;&amp;lt;br&amp;gt;+30 max resilience&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;With Hat:&#039;&#039;&#039;&amp;lt;br&amp;gt;+250/+475 max mana (+25 per tier)&amp;lt;br&amp;gt;+2 projectile bounces&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;With Any:&#039;&#039;&#039;&amp;lt;br&amp;gt;Press &#039;&#039;&#039;V&#039;&#039;&#039; to reduce all damage you&amp;lt;br&amp;gt;take to 1 for 5 seconds, but receive&amp;lt;br&amp;gt;considerably more knockback|images=[[File:Slime Armor Helmet Set.png]]&amp;lt;br&amp;gt;[[File:Slime Armor Hat Set.png]]}}&lt;br /&gt;
&lt;br /&gt;
===Nightsteel===&lt;br /&gt;
Endgame [[Incursion]] armor for all classes, higher defense but less offense for melee and mage classes compared to Slime Armor Set.&lt;br /&gt;
{{ArmorSetTable|Nightsteel Helmet/Nightsteel Mask/Nightsteel Veil/Nightsteel Circlet/Nightsteel Chestplate/Nightsteel Boots|total=90/84/82/77|setbonus=&#039;&#039;&#039;With Helmet:&#039;&#039;&#039;&amp;lt;br&amp;gt;+30 max resilience&amp;lt;br&amp;gt;+30% resilience gain&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;With Veil:&#039;&#039;&#039;&amp;lt;br&amp;gt;+250/+475 max mana (+25 per tier)&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;With Circlet:&#039;&#039;&#039;&amp;lt;br&amp;gt;+2 max summons&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;With Any:&#039;&#039;&#039;&amp;lt;br&amp;gt;Press &#039;&#039;&#039;V&#039;&#039;&#039; to get a boost and become&amp;lt;br&amp;gt;untargetable, but cannot attack&amp;lt;br&amp;gt;for 3 seconds|images=[[File:Nightsteel Armor Helmet Set.png]]&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;[[File:Nightsteel Armor Mask Set.png]]&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;[[File:Nightsteel Armor Veil Set.png]]&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;[[File:Nightsteel Armor Circlet Set.png]]}}&lt;br /&gt;
&lt;br /&gt;
===Spiderite===&lt;br /&gt;
Endgame [[Incursion]] armor for all classes.&lt;br /&gt;
{{ArmorSetTable|Spiderite Helmet/Spiderite Hood/Spiderite Hat/Spiderite Crown/Spiderite Chestplate/Spiderite Greaves|total=90/84/82/77|setbonus=&#039;&#039;&#039;With Helmet:&#039;&#039;&#039;&amp;lt;br&amp;gt;+20 max resilience&amp;lt;br&amp;gt;+50% resilience gain&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;With Hat:&#039;&#039;&#039;&amp;lt;br&amp;gt;+250/+475 max mana (+25 per tier)&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;With Crown:&#039;&#039;&#039;&amp;lt;br&amp;gt;+2 max summons&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;With Any:&#039;&#039;&#039;&amp;lt;br&amp;gt;Press &#039;&#039;&#039;V&#039;&#039;&#039; to manifest a line of toxic webs&amp;lt;br&amp;gt;for 10 seconds, 60 seconds cooldown&amp;lt;br&amp;gt;Grants immunity to slows|images=[[File:Spiderite Armor Helmet Set.png]]&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;[[File:Spiderite Armor Hood Set.png]]&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;[[File:Spiderite Armor Hat Set.png]]&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;[[File:Spiderite Armor Crown Set.png]]}}&lt;br /&gt;
&lt;br /&gt;
===Dusk===&lt;br /&gt;
Endgame [[Incursion]] armor for Magic and Summoner classes. Has the same base defense of its Dawn counterpart.&lt;br /&gt;
&lt;br /&gt;
Characters with a full set glow at night. &lt;br /&gt;
&lt;br /&gt;
{{ArmorSetTable|Dusk Helmet/Dusk Chestplate/Dusk Boots|total=90|setbonus=+400 max mana&amp;lt;br&amp;gt;Modifies Magic and Summon attacks during nighttime &#039;&#039;(19:00 to 7:00)&#039;&#039;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;Magic:&#039;&#039;&#039;&amp;lt;br&amp;gt;Shoots 5 homing Moonlit Bolts in random directions&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;Summon:&#039;&#039;&#039;&amp;lt;br&amp;gt;Summons 1 small Moon with each summoning that lasts for 5 seconds and flies&amp;lt;br&amp;gt;toward the target, dealing close-range damage &#039;&#039;(Maximum of 10 due to lifespan)&#039;&#039;|images=&#039;&#039;&#039;During Day&#039;&#039;&#039;&amp;lt;br&amp;gt;[[File:Dusk Armor Set.png|center]]&amp;lt;br&amp;gt;&#039;&#039;&#039;During Night&#039;&#039;&#039;&amp;lt;br&amp;gt;[[File:Dusk Armor Set Night.png|center]]}}&lt;br /&gt;
&lt;br /&gt;
===Dawn===&lt;br /&gt;
Endgame [[Incursion]] armor for Melee and Ranged classes. Has the same base defense of its Dusk counterpart.&lt;br /&gt;
{{ArmorSetTable|Dawn Helmet/Dawn Chestplate/Dawn Boots|total=90|setbonus=Modifies Melee and Ranged attacks during daytime &#039;&#039;(7:00 to 19:00)&#039;&#039;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;Melee:&#039;&#039;&#039;&amp;lt;br&amp;gt; Engulfs you in flames, exploding and applying Burning for 5 seconds&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;Ranged:&#039;&#039;&#039;&amp;lt;br&amp;gt;Shoots 2 Flame Orbs diagonally that pass through walls and applies burning for 10 seconds|images=&#039;&#039;&#039;During Day&#039;&#039;&#039;&amp;lt;br&amp;gt;[[File:Dawn Armor Set.png|center]]&amp;lt;br&amp;gt;&#039;&#039;&#039;During Night&#039;&#039;&#039;&amp;lt;br&amp;gt;[[File:Dawn Armor Set Night.png|center]]}}&lt;br /&gt;
&lt;br /&gt;
===Crystal===&lt;br /&gt;
Endgame [[Incursion]] armor for all classes.&lt;br /&gt;
{{ArmorSetTable|Amethyst Helmet/Sapphire Eyepatch/Emerald Mask/Ruby Crown/Crystal Chestplate/Crystal Boots|total=90|setbonus=&#039;&#039;&#039;With Helmet:&#039;&#039;&#039;&amp;lt;br&amp;gt;Deal 1% increased damage per 10 max resilience&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;With Eyepatch:&#039;&#039;&#039;&amp;lt;br&amp;gt;Press &#039;&#039;&#039;V&#039;&#039;&#039; to increase resilience regeneration&amp;lt;br&amp;gt;by 250% for 5 seconds, 45 seconds cooldown&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;With Mask:&#039;&#039;&#039;&amp;lt;br&amp;gt;You deal 50% more (magic) damage,&amp;lt;br&amp;gt;but take 25% more damage as well&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039;&#039;&#039;With Crown:&#039;&#039;&#039;&amp;lt;br&amp;gt;Increase max summons by 1 per 150 max resilience|images=[[File:Crystal Armor Amethyst Set.png|center]]&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;[[File:Crystal Armor Sapphire Set.png|center]]&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;[[File:Crystal Armor Emerald Set.png|center]]&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;[[File:Crystal Armor Ruby Set.png|center]]}}&lt;br /&gt;
&lt;br /&gt;
===Battle Chef&#039;s===&lt;br /&gt;
{{ArmorSetTable|Battle Chef&#039;s Hat/Battle Chef&#039;s Chestplate/Battle Chef&#039;s Boots|total=90|setbonus=You can now be affected by one more food buff at the same time|images=.}}&lt;br /&gt;
&lt;br /&gt;
===Ravenlord&#039;s===&lt;br /&gt;
Endgame [[Incursion]] armor for all classes. Fastest movement speed.&lt;br /&gt;
{{ArmorSetTable|Ravenlords Headdress/Ravenlords Chestplate/Ravenlords Boots|total=90|setbonus= Feathers spawn when moving, homing in on enemies&amp;lt;br&amp;gt;and dealing damage based on your movement speed|images=&#039;&#039;&#039;When Stationary:&#039;&#039;&#039;&amp;lt;br&amp;gt;[[File:Ravenlords Armor Set Stationary.png]]&amp;lt;br&amp;gt;&#039;&#039;&#039;When Moving:&#039;&#039;&#039;&amp;lt;br&amp;gt;[[File:Ravenlords Armor Set Moving.png]]}}&lt;br /&gt;
&lt;br /&gt;
===Arcanic===&lt;br /&gt;
Endgame Incursion armor for mages.&lt;br /&gt;
{{ArmorSetTable|Arcanic Helmet/Arcanic Chestplate/Arcanic Boots|total=90|setbonus=Press &#039;&#039;&#039;V&#039;&#039;&#039; to become Overcharged&amp;lt;br&amp;gt;While Overcharged, you drain 0.75% of your max mana every second, but also gain 2 stacks of Overcharged Mana for every point of mana lost&amp;lt;br&amp;gt;When you reach 20 stacks of Overcharged Mana, fire powerful lightning at nearby enemies}}&lt;br /&gt;
&lt;br /&gt;
{{Collapse bottom}}&lt;br /&gt;
.&lt;/div&gt;</summary>
		<author><name>Jamesp1989</name></author>
	</entry>
	<entry>
		<id>https://necessewiki.com/mediawiki/index.php?title=Guide:Getting_Started/Upgrading_Your_Gear&amp;diff=24580</id>
		<title>Guide:Getting Started/Upgrading Your Gear</title>
		<link rel="alternate" type="text/html" href="https://necessewiki.com/mediawiki/index.php?title=Guide:Getting_Started/Upgrading_Your_Gear&amp;diff=24580"/>
		<updated>2025-12-31T03:32:28Z</updated>

		<summary type="html">&lt;p&gt;Jamesp1989: /* Using your Forge */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Upgrading your gear==&lt;br /&gt;
===Making a Forge===&lt;br /&gt;
{{ItemList|compact|&lt;br /&gt;
|Now that we are back on the surface i&#039;m sure you are wanting to reap the rewards of your adventure. go ahead and open the {{Item|Workstation|inline=1}} and craft a {{Item|Forge|inline=1}}. To do this you will need:&amp;lt;br&amp;gt;&lt;br /&gt;
* {{Item|Stone|20}}&lt;br /&gt;
You should have more than enough from your time in the caves. Go ahead and craft it and then place it where you want.&lt;br /&gt;
}}&lt;br /&gt;
===Using your Forge===&lt;br /&gt;
{{ItemList|compact|&lt;br /&gt;
|Now that you have placed your forge you should place your mouse over it and right click. you will get the following window pop up:&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Forgeui.png|500px]]&amp;lt;br&amp;gt;&lt;br /&gt;
you will notice that there is a space for fuel which is required to use the forge. if you followed along with me you should have a bunch of trees around the elders house you can chop down for fuel. place some [[Logs]] in and you are ready to use the forge.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Take your ores that you obtained down in the caves and place them in the two slots on the left inside the forge, Bars will appear on the right hand side of the forge over time till it runs out of ore or fuel&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{tip|tip|It takes 4 ore to make one bar, but if you happened to find any {{Item|Broken Copper Tool|inline =1}} or {{Item|Broken Iron Tool|inline=1}} they can be put in the forge and only costs 1 of them to make the respective bar}}&lt;br /&gt;
&lt;br /&gt;
[[File:Forgerunning.gif|500px]]&lt;br /&gt;
{{tip|tip|If you put 2 different ores in the 2 slots available  it will process the ore on the right first}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===Making an Iron Anvil===&lt;br /&gt;
{{ItemList|compact|&lt;br /&gt;
|&lt;br /&gt;
The next thing we need is an {{Item|Iron Anvil|inline=1}} which is crafted with:&lt;br /&gt;
* {{Item|Iron Bar|5}}&lt;br /&gt;
Once you have made one place it where you like. we are finally ready to craft some [[Equipment]]&lt;br /&gt;
}}&lt;br /&gt;
===Crafting Equipment===&lt;br /&gt;
{{ItemList|compact|&lt;br /&gt;
|&lt;br /&gt;
Head over to your anvil and you should see something like this:&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Anvilui.png|500px]]&amp;lt;br&amp;gt;&lt;br /&gt;
{{tip|tip|there is a tick box down on the bottom left that says &amp;quot;Use nearby inventories&amp;quot; if this is left ticked you can use items from nearby {{Item|Storagebox|inline=1}} instead of having to have the items in your inventory}}}}&lt;br /&gt;
====Armor and Weapons upgrade loop====&lt;br /&gt;
{{ItemList|compact|&lt;br /&gt;
|&lt;br /&gt;
now we need to go back to our {{Item|Forge|inline=1}} with all the ores we have from our first trip down in the caves and smelt everything we have currently. right now you will likely have mostly&lt;br /&gt;
* {{item|Copper Ore|inline=1}} &lt;br /&gt;
* {{item|Iron Ore|inline=1}} &lt;br /&gt;
so smelt them down to bars and then head over to the {{item|Iron Anvil|inline=1}} to make some armor&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
{{tip|tip|Different [[Armor]] have different set perks which are usually geared towards the different fighting styles in the game. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The style you want will usually depend on what your [[Weapon]] of choice is. and we will go more into the what the different styles are good at later.}}&lt;br /&gt;
For now you just want to make the best armor you can so go over and take a look at the anvil.&lt;br /&gt;
&lt;br /&gt;
take a look at the pieces for the armor in the {{item|Iron Anvil|inline=1}} and it will tell you how much of each material you need to craft it. in the case of copper equipment you need:&lt;br /&gt;
}}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Copper Gear&lt;br /&gt;
|-&lt;br /&gt;
! Header text !! Header text&lt;br /&gt;
|-&lt;br /&gt;
| {{item|Copper Bar|inline=1|12}} || {{item|Copper Helmet}}&lt;br /&gt;
|-&lt;br /&gt;
| {{item|Copper Bar|inline=1}|16}} || {{item|Copper Chestplate}}&lt;br /&gt;
|-&lt;br /&gt;
| {{item|Copper Bar|inline=1|8}} || {{item|Copper Boots}}&lt;br /&gt;
|-&lt;br /&gt;
| {{item|Copper Bar|8}}{{item|Any Log|1}} || {{item|Copper Pickaxe}}&lt;br /&gt;
|-&lt;br /&gt;
| {{item|Copper Bar|10}}{{item|Any Log|1}} || {{item|Copper Sword}}&lt;br /&gt;
|}&lt;br /&gt;
{{tip|tip|This is not an extensive list of what you can make with these bars. you can go right to making iron equipment if you have enough resources}}{{ItemList|compact|&lt;br /&gt;
|The idea is to do this with the best equipment you can currently craft and then head back down to the caves and repeat the process of gathering materials&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Once you have a full set of Copper Equipment you should try to move to making Iron equipment and finally Gold equipment. &lt;br /&gt;
}}&lt;br /&gt;
===Enchanting your gear===&lt;br /&gt;
{{ItemList|compact|&lt;br /&gt;
|&lt;br /&gt;
enchanting your gear is very important to give yourself that extra edge. at this point in the game you only have access to enchanting via {{item|Enchanting Scroll|inline=1}} which you will hopefully have found some while down in the caves!&amp;lt;br&amp;gt;&amp;lt;br&amp;gt; Each enchanting scroll is for a specific type of equipment and the description when you hover over the scroll will let you know what it is for. you right click on the scroll you want to use and then drag the piece of equipment you want to enchant into the slot and then press the enchant button.&lt;br /&gt;
{{tip|note|the scroll item is one time use and you will lose it on use but equipment can have its enchantment changed as often as you like}}&lt;br /&gt;
[[File:Enchanting.gif|300px]]&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
In this instance i applied the Sturdy enchantment to my armor giving it an aditional +4 armor.&lt;br /&gt;
}}&lt;br /&gt;
===To The Snow Biome===&lt;br /&gt;
{{tip|tip|This was my build before entering the [[Caves|Snow Caves]]. you can mouse over the different pieces of gear to see what they are and mouse over the [[File:Enchantingscroll_equipment.png]] icon to see what they were enchanted with}}&lt;br /&gt;
{{NecesseBuild&lt;br /&gt;
 |trinket1=Fuzzy Dice&lt;br /&gt;
 |trinket1_enchant=Precise(+4% Crit Chance)&lt;br /&gt;
 |trinket2=Zephyr Charm&lt;br /&gt;
 |trinket3=Shine Belt&lt;br /&gt;
 |trinket3_enchant=Sturdy(+4 Armor)&lt;br /&gt;
 |trinket4=Noble Horseshoe&lt;br /&gt;
 |trinket4_enchant=Nimble(+4% Movement speed)&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 |cosmetic_hat=&lt;br /&gt;
 |cosmetic_chest=&lt;br /&gt;
 |cosmetic_feet=&lt;br /&gt;
 |ability_trinket=Leather Dashers&lt;br /&gt;
 |ability_trinket_enchant=Quick(+4% Attack Speed)&lt;br /&gt;
&lt;br /&gt;
 |armor_head=Gold Helmet&lt;br /&gt;
 |armor_head_enchant=Sturdy(+4 Armor)&lt;br /&gt;
 |armor_chest=Gold Chestplate&lt;br /&gt;
 |armor_chest_enchant=Sturdy(+4 Armor)&lt;br /&gt;
 |armor_feet=Gold Boots&lt;br /&gt;
 |armor_feet_enchant=Sturdy(+4 Armor)&lt;br /&gt;
 |mount=Minecart&lt;br /&gt;
 |hotbar1=Gold Pickaxe&lt;br /&gt;
&lt;br /&gt;
 |hotbar2=Wood Axe&lt;br /&gt;
&lt;br /&gt;
 |hotbar3=Gold Sword&lt;br /&gt;
&lt;br /&gt;
 |hotbar4=Gold Bow&lt;br /&gt;
 |hotbar4_qty=40&lt;br /&gt;
&lt;br /&gt;
 |hotbar5=Bread&lt;br /&gt;
 |hotbar5_qty=9&lt;br /&gt;
&lt;br /&gt;
 |hotbar6=Blueberry&lt;br /&gt;
 |hotbar6_qty=12&lt;br /&gt;
&lt;br /&gt;
 |hotbar7=Health Potion&lt;br /&gt;
 |hotbar7_qty=5&lt;br /&gt;
}}&lt;br /&gt;
{{tip|map|there is one more ore above gold that we have access to before the first boss {{item|Frost Shard|inline=1}} which we will be needing to upgrade to but its not found here in the forest caves, so once you have full gold equipment you are ready to visit the snow biome for [[Guide:Getting Started/A Snowy Encounter|a snowy encounter]]}}&lt;/div&gt;</summary>
		<author><name>Jamesp1989</name></author>
	</entry>
	<entry>
		<id>https://necessewiki.com/mediawiki/index.php?title=Stat_Modifier&amp;diff=24579</id>
		<title>Stat Modifier</title>
		<link rel="alternate" type="text/html" href="https://necessewiki.com/mediawiki/index.php?title=Stat_Modifier&amp;diff=24579"/>
		<updated>2025-12-31T03:11:55Z</updated>

		<summary type="html">&lt;p&gt;Jamesp1989: /* Movement */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Stat Modifiers ==&lt;br /&gt;
&lt;br /&gt;
[[Armor]] and [[Weapons]] as well as [[Potions]],[[Food]] and even the enviroment itself such as [[Lava]] can apply positive or negative effects to the players stats&lt;br /&gt;
 &lt;br /&gt;
== Damage ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Damage Modifiers&lt;br /&gt;
|-&lt;br /&gt;
! Modifier !! Effect !! Notes&lt;br /&gt;
|-&lt;br /&gt;
| Damage || X% Damage dealt || Overall damage modifier&lt;br /&gt;
|-&lt;br /&gt;
| Melee Damage || X% Melee damage dealt || Applies to melee attacks&lt;br /&gt;
|-&lt;br /&gt;
| Ranged Damage || X% Ranged damage dealt || Applies to ranged attacks&lt;br /&gt;
|-&lt;br /&gt;
| Magic Damage || X% Magic damage dealt || Applies to magic attacks&lt;br /&gt;
|-&lt;br /&gt;
| Summon Damage || X% Summon damage dealt || Applies to summons and minions&lt;br /&gt;
|-&lt;br /&gt;
| Fire Damage || X Fire Damage || Applies damage of X per second over time.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Critical ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Critical Modifiers&lt;br /&gt;
|-&lt;br /&gt;
! Modifier !! Effect !! Notes&lt;br /&gt;
|-&lt;br /&gt;
| Critical Chance || X% Critical hit chance || Chance for attacks to crit&lt;br /&gt;
|-&lt;br /&gt;
| Critical Damage || X% Critical damage || Damage multiplier on critical hits&lt;br /&gt;
|-&lt;br /&gt;
| Melee Critical Damage || X% Melee critical damage || Extra crit damage for melee&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Attack Speed ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Attack Speed Modifiers&lt;br /&gt;
|-&lt;br /&gt;
! Modifier !! Effect !! Notes&lt;br /&gt;
|-&lt;br /&gt;
| Attack Speed || X% Attack speed || Overall attack speed&lt;br /&gt;
|-&lt;br /&gt;
| Melee Attack Speed || X% Melee attack speed || Melee weapons only&lt;br /&gt;
|-&lt;br /&gt;
| Ranged Attack Speed || X% Ranged attack speed || Ranged weapons only&lt;br /&gt;
|-&lt;br /&gt;
| Magic Attack Speed || X% Magic attack speed || Magic weapons only&lt;br /&gt;
|-&lt;br /&gt;
| Summon Speed || X% Summon speed || Summon attack speed&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Movement ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Movement Modifiers&lt;br /&gt;
|-&lt;br /&gt;
! Modifier !! Effect !! Notes&lt;br /&gt;
|-&lt;br /&gt;
| Movement Speed || X Movement speed || Player movement speed&lt;br /&gt;
|-&lt;br /&gt;
| Attack Movement Penalty || X% Attack movement penalty || Slowdown while attacking&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Defense ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Defense Modifiers&lt;br /&gt;
|-&lt;br /&gt;
! Modifier !! Effect !! Notes&lt;br /&gt;
|-&lt;br /&gt;
| Armor || X Armor || Flat damage reduction&lt;br /&gt;
|-&lt;br /&gt;
| Damage Taken || X% Damage taken || Modifies incoming damage&lt;br /&gt;
|-&lt;br /&gt;
| Knockback Resistance || X% Knockback resistance || Reduces knockback taken&lt;br /&gt;
|-&lt;br /&gt;
| Max Knockback || X% Maximum knockback || Upper limit of knockback taken&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Health ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Health Modifiers&lt;br /&gt;
|-&lt;br /&gt;
! Modifier !! Effect !! Notes&lt;br /&gt;
|-&lt;br /&gt;
| Max Health || X Maximum health || Total health pool&lt;br /&gt;
|-&lt;br /&gt;
| Health Regen || X Health regeneration || Health recovery rate&lt;br /&gt;
|-&lt;br /&gt;
| Max X% Health Regen || X Maximum health || How much health can regen as a percentage&lt;br /&gt;
|-&lt;br /&gt;
| Max X% Out Of Combat Health Regen || X Maximum health || How much health can regen outside of combat as a percentage&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Resilience ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Resilience Modifiers&lt;br /&gt;
|-&lt;br /&gt;
! Modifier !! Effect !! Notes&lt;br /&gt;
|-&lt;br /&gt;
| Max Resilience || X Maximum resilience || Total resilience pool&lt;br /&gt;
|-&lt;br /&gt;
| Resilience Gain || X% Resilience gain || Gained from dealing damage&lt;br /&gt;
|-&lt;br /&gt;
| Resilience Decay || X% Resilience decay || Rate resilience decreases&lt;br /&gt;
|-&lt;br /&gt;
| Resilience Regeneration || X Resilience regeneration || Passive resilience recovery&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Mana ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Mana Modifiers&lt;br /&gt;
|-&lt;br /&gt;
! Modifier !! Effect !! Notes&lt;br /&gt;
|-&lt;br /&gt;
| Max Mana || X Maximum mana || Total mana pool&lt;br /&gt;
|-&lt;br /&gt;
| Mana Regeneration || X% Mana regeneration || Mana recovery rate&lt;br /&gt;
|-&lt;br /&gt;
| Mana Cost || X% Mana cost || Mana usage modifier&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Stamina ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Stamina Modifiers&lt;br /&gt;
|-&lt;br /&gt;
! Modifier !! Effect !! Notes&lt;br /&gt;
|-&lt;br /&gt;
| Stamina Regeneration || X% Stamina regeneration || Stamina recovery rate&lt;br /&gt;
|-&lt;br /&gt;
| Stamina Cost || X% Stamina cost || Stamina usage modifier&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Projectiles ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Projectile Modifiers&lt;br /&gt;
|-&lt;br /&gt;
! Modifier !! Effect !! Notes&lt;br /&gt;
|-&lt;br /&gt;
| Projectile Velocity || X% Projectile velocity || Projectile travel speed&lt;br /&gt;
|-&lt;br /&gt;
| Projectile Range || X% Projectile range || Projectile travel distance&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Summons ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Summon Modifiers&lt;br /&gt;
|-&lt;br /&gt;
! Modifier !! Effect !! Notes&lt;br /&gt;
|-&lt;br /&gt;
| Max Summons || X Maximum summons || Number of active summons&lt;br /&gt;
|-&lt;br /&gt;
| Summon Target Range || X% Summon target range || Targeting distance&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Utility ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Utility Modifiers&lt;br /&gt;
|-&lt;br /&gt;
! Modifier !! Effect !! Notes&lt;br /&gt;
|-&lt;br /&gt;
| Dash Charges || X Dash charges || Number of dash uses&lt;br /&gt;
|-&lt;br /&gt;
| Ammo Consumption || X% Ammo consumption || Chance to consume ammo&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Jamesp1989</name></author>
	</entry>
	<entry>
		<id>https://necessewiki.com/mediawiki/index.php?title=Guide:Getting_Started&amp;diff=24578</id>
		<title>Guide:Getting Started</title>
		<link rel="alternate" type="text/html" href="https://necessewiki.com/mediawiki/index.php?title=Guide:Getting_Started&amp;diff=24578"/>
		<updated>2025-12-31T03:08:48Z</updated>

		<summary type="html">&lt;p&gt;Jamesp1989: /* Food */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Getting Started Guide ==&lt;br /&gt;
&lt;br /&gt;
{{tip|tip|Welcome to the wonderful world of &#039;&#039;&#039;Necesse&#039;&#039;&#039;. This game may seem slightly overwhelming but let me reassure you, the basics of this game can be learned quite easily.}}&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Joining A World For The First Time ===&lt;br /&gt;
&lt;br /&gt;
When starting a new world or joining a multiplayer world for the first time you will need to create a new character we call [[The Player]].&lt;br /&gt;
&lt;br /&gt;
{{Tip|note|Your character can be reused across multiple worlds, so don’t worry too much about early choices.}}&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Create player.jpg|300px]]&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Your Starting Location ===&lt;br /&gt;
&lt;br /&gt;
Once you load into the world I suggest you head into the house you spawn by and take a look at the&lt;br /&gt;
[[Guide:Getting_Started/User Interface|User Interface]] and [[Controls]] pages to familiarise yourself with them.&lt;br /&gt;
&lt;br /&gt;
{{Tip|tip|Knowing your controls early will make combat and exploration much easier later on.}}&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:The Elders House.png|500px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;The player&#039;s default spawn point near the Elder&#039;s House.&#039;&#039;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Player Inventory ===&lt;br /&gt;
{{ItemList|compact|The player&#039;s starting inventory includes:&lt;br /&gt;
|&lt;br /&gt;
* {{Item|Wood Axe|inline=1}}&lt;br /&gt;
* {{Item|Wood Sword|inline=1}}&lt;br /&gt;
* {{Item|Crafting Guide|inline=1}}{{Tip|note|These starting tools are enough to begin gathering resources and crafting basic equipment.}}}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:The Players Starting Inventory.png|500px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;Starting inventory.&#039;&#039;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{ItemList|compact|&lt;br /&gt;
|&lt;br /&gt;
== The Elders House ==&lt;br /&gt;
In new worlds, the player spawns in a [[Forest Biome]] next to the house of the [[Elder]], if the corresponding option was selected when creating the world.&lt;br /&gt;
The [[Elder]] is your game guide and [[quests]] giver. He will provide useful and sometimes unique rewards for completing quests, so don&#039;t ignore him.&lt;br /&gt;
&lt;br /&gt;
{{Tip|tip|Completing the Elder’s quests is one of the easiest ways to follow intended [[Guide:Getting_Started/Progression|Progression]]}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{ItemList|compact|&lt;br /&gt;
|&lt;br /&gt;
=== Inside the Elders House ===&lt;br /&gt;
In the Elder&#039;s house, the player will find a {{Item|Workstation|inline=1}} where they can craft their first equipment needed for the further exploration, such as:&lt;br /&gt;
* {{Item|Wood Pickaxe|inline=1}}&lt;br /&gt;
* {{Item|Wood Shovel|inline=1}}&lt;br /&gt;
* {{Item|Wood Boat|inline=1}}&lt;br /&gt;
* {{Item|Torches|inline=1}}&lt;br /&gt;
There is also a {{Item|Spruce Display|inline=1}} which holds:&lt;br /&gt;
* a pair of {{Item|Leather Dashers|inline=1}}&lt;br /&gt;
{{Tip|tip|[[Leather Dashers]] are an [[Trinkets#Ability Trinkets|Ability Trinket]] which allows the player to [[Dashing|Dash]] at the expense of [[Stamina]].&lt;br /&gt;
}}}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{ItemList|compact|&lt;br /&gt;
|&lt;br /&gt;
==== Spawn Points and Beds ====&lt;br /&gt;
The Elder&#039;s {{item|Bed|inline=1}} can be used to set a spawn point inside the house.&amp;lt;br&amp;gt;&lt;br /&gt;
This is the place the player will return to when they die.&lt;br /&gt;
{{tip|note|You will be able to craft your own beds later.Beds can be used to skip between day and night if all players are in bed. we will go more into the day and night cycle shortly}}}}&lt;br /&gt;
{{ItemList|compact|&lt;br /&gt;
|&lt;br /&gt;
==== The Elder&#039;s Storagebox ====&lt;br /&gt;
There is a {{Item|Storagebox|inline=1}} in the elders house that the player can take items from which contains:&lt;br /&gt;
* {{Item|Village Map|inline=1}}&lt;br /&gt;
* {{Item|Dungeon Map|inline=1}}&lt;br /&gt;
* {{Item|Bread|inline=1}}&lt;br /&gt;
* {{Item|Health Potion|inline=1}}&lt;br /&gt;
* {{Item|Settlement Flag|inline=1}}&lt;br /&gt;
{{Tip|note|A [[Settlement Flag]] is used to start a [[Settlements|settlement]].  &lt;br /&gt;
The flag can be placed on any [[terrain]] [[Tiles|tile]] outside or inside the house. Go ahead and do this now as we will need it placed later to take a quest from the elder, We will cover [[Guide:Getting_Started/Settlements|Settlements]] in more detail later in the guide}}}}&lt;br /&gt;
{{ItemList|compact|&lt;br /&gt;
|&lt;br /&gt;
==== Cave Ladder ====&lt;br /&gt;
{{Tip|warning|The elders house also has a {{Item|Cave Ladder|inline=1}} to go down into the [[Caves]] but we arent quite ready for that yet.}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{ItemList|compact|&lt;br /&gt;
|&lt;br /&gt;
=== Outside the Elders House ===&lt;br /&gt;
Outside the house is a {{Item|Roasting Station|inline=1}} on top of a {{Item|Campfire|inline=1}} which you can use to cook raw meat from:&lt;br /&gt;
* {{Item|Cow|inline=1}}&lt;br /&gt;
* {{Item|Sheep|inline=1}} &lt;br /&gt;
and other [[Animals]]&lt;br /&gt;
&lt;br /&gt;
{{Tip|note|It&#039;s best not to kill the animals near your spawn as you can use them later for [[Animals#Taming|Taming]], [[Animals#Breeding|Breeding]] and [[Animals#Harvesting|Harvesting]].}}}}&lt;br /&gt;
&lt;br /&gt;
=Exploring the World=&lt;br /&gt;
===Day And Night Cycle===&lt;br /&gt;
{{tip|note|The world has a day and night cycle. in the forest nothing hostile will spawn during the day but [[Zombie]]s come out at night so be sure to take shelter or be prepared to fight }}&lt;br /&gt;
&lt;br /&gt;
== Obtaining Mining Gear ==&lt;br /&gt;
{{ItemList|compact|Head outside of the [[elder]]s house and chop down some [[Trees]].&lt;br /&gt;
|&lt;br /&gt;
In the forest it will be either:&lt;br /&gt;
* {{item|Oak Tree|inline=1|size=32px}}&lt;br /&gt;
* {{item|Spruce Tree|inline=1|size=32px}}&lt;br /&gt;
{{tip|tip|You can chop trees down with the {{item|Wood Axe|inline=1}} that came in your starting inventory and collect the [[Logs]] and [[Saplings]] that drop. &lt;br /&gt;
&lt;br /&gt;
You should cut down more than you need so that you can use the extra logs to craft more torches and replant the saplings near the elders house to grow over time.&lt;br /&gt;
}}}}&lt;br /&gt;
{{ItemList|compact|&lt;br /&gt;
|&lt;br /&gt;
Before We head down to the [[Caves]] we need at least: &lt;br /&gt;
* {{item|Oak Log|inline=1|size=32px|2}} to make a {{item|Wood Pickaxe|inline=1}} &lt;br /&gt;
* 10 logs and 10 saplings to make {{item|Torch|inline=1|size=32px|40}}&lt;br /&gt;
{{Tip|warning|Torches are essential in caves — darkness hides enemies and hazards.}}}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{ItemList|compact|Once you have all of these head over to the {{item|Workstation|inline=1}} inside the [[Elder]]s house and craft:&lt;br /&gt;
|&lt;br /&gt;
* {{item|Wood Pickaxe|inline=1}}&lt;br /&gt;
* {{item|Torch|inline=1|40}}&lt;br /&gt;
}}&lt;br /&gt;
= Food =&lt;br /&gt;
{{ItemList|compact|&lt;br /&gt;
|&lt;br /&gt;
{{tip|tip|&amp;lt;br&amp;gt;Food items are very important in Necesse and not just to stave off [[Guide:Getting_Started/User_Interface#Hunger|hunger]]:&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;not only do different food items restore your hunger by differing amounts they also all give the player buffs dependant on the food item consumed.&amp;lt;br&amp;gt; &lt;br /&gt;
Food items can be separated into Raw, Fine and Gourmet with the buffs received getting better the higher the quality of food is, but we will go into that later }}{{tip|warning|you can only have one food buff at a time and consuming another will remove the previous buff instantly}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{ItemList|compact|&lt;br /&gt;
|&lt;br /&gt;
== Food Buffs ==&lt;br /&gt;
I wont go into a great deal about the different food or food buffs right now but I will cover the first few you are likely to encounter:&lt;br /&gt;
===[[Simple Food]]===&lt;br /&gt;
====Fruits ====&lt;br /&gt;
These are classed as simple raw foods that have a positive buff when eaten:&lt;br /&gt;
* {{Item|Apple|inline=1|+2% Movement Speed}}&lt;br /&gt;
* {{Item|Blueberry|inline=1|+2% Crit Chance}}&lt;br /&gt;
==== Raw Meat ====&lt;br /&gt;
These are raw meats. you shouldn&#039;t eat these without [[Guide:Getting_Started#Outside the Elders House|cooking them]] otherwise you will take 10 damage&lt;br /&gt;
* {{Item|Beef|inline=1|-10 Health}}(becomes {{Item|Steak|inline=1}} when cooked)&lt;br /&gt;
* {{Item|Raw Mutton|inline=1|-10 Health}}(becomes {{Item|Roasted Mutton|inline=1}} when cooked)&lt;br /&gt;
=== [[Fine Food]]s ===&lt;br /&gt;
* {{Item|Steak|inline=1|+2% Damage}}&lt;br /&gt;
* {{Item|Roasted Mutton|inline=1|+2% Crit Chance}}&lt;br /&gt;
* {{Item|Bread|inline=1|+20 Max Health}}&lt;br /&gt;
}}&lt;br /&gt;
== Food Spoilage ==&lt;br /&gt;
&lt;br /&gt;
{{tip|tip|&lt;br /&gt;
Food in your backpack and regular {{Item|Storagebox|inline=1}} will spoil over time and different foods have their own spoil times. once this time reaches 0 it becomes {{item|Spoiled Food|inline=1}} which has its own uses which we will get into later&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
= Final Preparations =&lt;br /&gt;
&lt;br /&gt;
{{ItemList|compact|If you haven&#039;t already make sure you grab:&lt;br /&gt;
|&lt;br /&gt;
* {{item|Bread|inline=1}}&lt;br /&gt;
* {{item|Health Potion|inline=1}} &lt;br /&gt;
&lt;br /&gt;
from the chest or: &lt;br /&gt;
* find some {{item|Blueberry|inline=1}} from {{item|Blueberry Bush|inline=1|size=32px}} in the surrounding forest.&lt;br /&gt;
{{Tip|tip|If you come across any {{item|Blueberry Bush|inline=1|size=32px}} you should break these and place them near the elders house as an early source of food.&lt;br /&gt;
&lt;br /&gt;
Carrying food and healing items greatly increases your survival chances underground.}}}}&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Your inventory should look a little like this:&lt;br /&gt;
&lt;br /&gt;
{{NecesseBuild&lt;br /&gt;
 |cosmetic_feet=Shoes&lt;br /&gt;
 |ability_trinket=Leather Dashers&lt;br /&gt;
&lt;br /&gt;
 |hotbar1=Wood Pickaxe&lt;br /&gt;
 |hotbar2=Wood Axe&lt;br /&gt;
 |hotbar3=Wood Sword&lt;br /&gt;
&lt;br /&gt;
 |hotbar4=Torch&lt;br /&gt;
 |hotbar4_qty=40&lt;br /&gt;
&lt;br /&gt;
 |hotbar5=Bread&lt;br /&gt;
 |hotbar5_qty=9&lt;br /&gt;
&lt;br /&gt;
 |hotbar6=Blueberry&lt;br /&gt;
 |hotbar6_qty=12&lt;br /&gt;
&lt;br /&gt;
 |hotbar7=Health Potion&lt;br /&gt;
 |hotbar7_qty=5&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Down We Go ===&lt;br /&gt;
&lt;br /&gt;
{{Tip|map|If you feel unsure, you can always gather more supplies before entering the caves.&amp;lt;br&amp;gt;&lt;br /&gt;
Head over to the cave ladder for&lt;br /&gt;
[[Guide:Getting_Started/Your_First_Cave|Your First Cave]]&lt;br /&gt;
when you feel comfortable you have everything you need.}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Guides]]&lt;/div&gt;</summary>
		<author><name>Jamesp1989</name></author>
	</entry>
	<entry>
		<id>https://necessewiki.com/mediawiki/index.php?title=Guide:Getting_Started/Upgrading_Your_Gear&amp;diff=24577</id>
		<title>Guide:Getting Started/Upgrading Your Gear</title>
		<link rel="alternate" type="text/html" href="https://necessewiki.com/mediawiki/index.php?title=Guide:Getting_Started/Upgrading_Your_Gear&amp;diff=24577"/>
		<updated>2025-12-31T02:58:32Z</updated>

		<summary type="html">&lt;p&gt;Jamesp1989: /* To The Snow Biome */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Upgrading your gear==&lt;br /&gt;
===Making a Forge===&lt;br /&gt;
{{ItemList|compact|&lt;br /&gt;
|Now that we are back on the surface i&#039;m sure you are wanting to reap the rewards of your adventure. go ahead and open the {{Item|Workstation|inline=1}} and craft a {{Item|Forge|inline=1}}. To do this you will need:&amp;lt;br&amp;gt;&lt;br /&gt;
* {{Item|Stone|20}}&lt;br /&gt;
You should have more than enough from your time in the caves. Go ahead and craft it and then place it where you want.&lt;br /&gt;
}}&lt;br /&gt;
===Using your Forge===&lt;br /&gt;
{{ItemList|compact|&lt;br /&gt;
|Now that you have placed your forge you should place your mouse over it and right click. you will get the following window pop up:&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Forgeui.png|500px]]&amp;lt;br&amp;gt;&lt;br /&gt;
you will notice that there is a space for fuel which is required to use the forge. if you followed along with me you should have a bunch of trees around the elders house you can chop down for fuel. place some [[Logs]] in and you are ready to use the forge.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Take your ores that you obtained down in the caves and place them in the two slots on the left inside the forge, Bars will appear on the right hand side of the forge over time till it runs out of ore or fuel&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{tip|tip|It takes 4 ore to make one bar, but if you happened to find any {{Item|Broken Copper Tool|inline =1}} or {{Item|Broken Iron Tool|inline=1}} they can be put in the forge and only costs 1 of them to make the respective bar}}&lt;br /&gt;
&lt;br /&gt;
[[File:Forgerunning.gif|400px]]&lt;br /&gt;
{{tip|tip|If you put 2 different ores in the 2 slots available  it will process the ore on the right first}}&lt;br /&gt;
}}&lt;br /&gt;
===Making an Iron Anvil===&lt;br /&gt;
{{ItemList|compact|&lt;br /&gt;
|&lt;br /&gt;
The next thing we need is an {{Item|Iron Anvil|inline=1}} which is crafted with:&lt;br /&gt;
* {{Item|Iron Bar|5}}&lt;br /&gt;
Once you have made one place it where you like. we are finally ready to craft some [[Equipment]]&lt;br /&gt;
}}&lt;br /&gt;
===Crafting Equipment===&lt;br /&gt;
{{ItemList|compact|&lt;br /&gt;
|&lt;br /&gt;
Head over to your anvil and you should see something like this:&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Anvilui.png|500px]]&amp;lt;br&amp;gt;&lt;br /&gt;
{{tip|tip|there is a tick box down on the bottom left that says &amp;quot;Use nearby inventories&amp;quot; if this is left ticked you can use items from nearby {{Item|Storagebox|inline=1}} instead of having to have the items in your inventory}}}}&lt;br /&gt;
====Armor and Weapons upgrade loop====&lt;br /&gt;
{{ItemList|compact|&lt;br /&gt;
|&lt;br /&gt;
now we need to go back to our {{Item|Forge|inline=1}} with all the ores we have from our first trip down in the caves and smelt everything we have currently. right now you will likely have mostly&lt;br /&gt;
* {{item|Copper Ore|inline=1}} &lt;br /&gt;
* {{item|Iron Ore|inline=1}} &lt;br /&gt;
so smelt them down to bars and then head over to the {{item|Iron Anvil|inline=1}} to make some armor&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
{{tip|tip|Different [[Armor]] have different set perks which are usually geared towards the different fighting styles in the game. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The style you want will usually depend on what your [[Weapon]] of choice is. and we will go more into the what the different styles are good at later.}}&lt;br /&gt;
For now you just want to make the best armor you can so go over and take a look at the anvil.&lt;br /&gt;
&lt;br /&gt;
take a look at the pieces for the armor in the {{item|Iron Anvil|inline=1}} and it will tell you how much of each material you need to craft it. in the case of copper equipment you need:&lt;br /&gt;
}}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Copper Gear&lt;br /&gt;
|-&lt;br /&gt;
! Header text !! Header text&lt;br /&gt;
|-&lt;br /&gt;
| {{item|Copper Bar|inline=1|12}} || {{item|Copper Helmet}}&lt;br /&gt;
|-&lt;br /&gt;
| {{item|Copper Bar|inline=1}|16}} || {{item|Copper Chestplate}}&lt;br /&gt;
|-&lt;br /&gt;
| {{item|Copper Bar|inline=1|8}} || {{item|Copper Boots}}&lt;br /&gt;
|-&lt;br /&gt;
| {{item|Copper Bar|8}}{{item|Any Log|1}} || {{item|Copper Pickaxe}}&lt;br /&gt;
|-&lt;br /&gt;
| {{item|Copper Bar|10}}{{item|Any Log|1}} || {{item|Copper Sword}}&lt;br /&gt;
|}&lt;br /&gt;
{{tip|tip|This is not an extensive list of what you can make with these bars. you can go right to making iron equipment if you have enough resources}}{{ItemList|compact|&lt;br /&gt;
|The idea is to do this with the best equipment you can currently craft and then head back down to the caves and repeat the process of gathering materials&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Once you have a full set of Copper Equipment you should try to move to making Iron equipment and finally Gold equipment. &lt;br /&gt;
}}&lt;br /&gt;
===Enchanting your gear===&lt;br /&gt;
{{ItemList|compact|&lt;br /&gt;
|&lt;br /&gt;
enchanting your gear is very important to give yourself that extra edge. at this point in the game you only have access to enchanting via {{item|Enchanting Scroll|inline=1}} which you will hopefully have found some while down in the caves!&amp;lt;br&amp;gt;&amp;lt;br&amp;gt; Each enchanting scroll is for a specific type of equipment and the description when you hover over the scroll will let you know what it is for. you right click on the scroll you want to use and then drag the piece of equipment you want to enchant into the slot and then press the enchant button.&lt;br /&gt;
{{tip|note|the scroll item is one time use and you will lose it on use but equipment can have its enchantment changed as often as you like}}&lt;br /&gt;
[[File:Enchanting.gif|300px]]&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
In this instance i applied the Sturdy enchantment to my armor giving it an aditional +4 armor.&lt;br /&gt;
}}&lt;br /&gt;
===To The Snow Biome===&lt;br /&gt;
{{tip|tip|This was my build before entering the [[Caves|Snow Caves]]. you can mouse over the different pieces of gear to see what they are and mouse over the [[File:Enchantingscroll_equipment.png]] icon to see what they were enchanted with}}&lt;br /&gt;
{{NecesseBuild&lt;br /&gt;
 |trinket1=Fuzzy Dice&lt;br /&gt;
 |trinket1_enchant=Precise(+4% Crit Chance)&lt;br /&gt;
 |trinket2=Zephyr Charm&lt;br /&gt;
 |trinket3=Shine Belt&lt;br /&gt;
 |trinket3_enchant=Sturdy(+4 Armor)&lt;br /&gt;
 |trinket4=Noble Horseshoe&lt;br /&gt;
 |trinket4_enchant=Nimble(+4% Movement speed)&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 |cosmetic_hat=&lt;br /&gt;
 |cosmetic_chest=&lt;br /&gt;
 |cosmetic_feet=&lt;br /&gt;
 |ability_trinket=Leather Dashers&lt;br /&gt;
 |ability_trinket_enchant=Quick(+4% Attack Speed)&lt;br /&gt;
&lt;br /&gt;
 |armor_head=Gold Helmet&lt;br /&gt;
 |armor_head_enchant=Sturdy(+4 Armor)&lt;br /&gt;
 |armor_chest=Gold Chestplate&lt;br /&gt;
 |armor_chest_enchant=Sturdy(+4 Armor)&lt;br /&gt;
 |armor_feet=Gold Boots&lt;br /&gt;
 |armor_feet_enchant=Sturdy(+4 Armor)&lt;br /&gt;
 |mount=Minecart&lt;br /&gt;
 |hotbar1=Gold Pickaxe&lt;br /&gt;
&lt;br /&gt;
 |hotbar2=Wood Axe&lt;br /&gt;
&lt;br /&gt;
 |hotbar3=Gold Sword&lt;br /&gt;
&lt;br /&gt;
 |hotbar4=Gold Bow&lt;br /&gt;
 |hotbar4_qty=40&lt;br /&gt;
&lt;br /&gt;
 |hotbar5=Bread&lt;br /&gt;
 |hotbar5_qty=9&lt;br /&gt;
&lt;br /&gt;
 |hotbar6=Blueberry&lt;br /&gt;
 |hotbar6_qty=12&lt;br /&gt;
&lt;br /&gt;
 |hotbar7=Health Potion&lt;br /&gt;
 |hotbar7_qty=5&lt;br /&gt;
}}&lt;br /&gt;
{{tip|map|there is one more ore above gold that we have access to before the first boss {{item|Frost Shard|inline=1}} which we will be needing to upgrade to but its not found here in the forest caves, so once you have full gold equipment you are ready to visit the snow biome for [[Guide:Getting Started/A Snowy Encounter|a snowy encounter]]}}&lt;/div&gt;</summary>
		<author><name>Jamesp1989</name></author>
	</entry>
	<entry>
		<id>https://necessewiki.com/mediawiki/index.php?title=Guide:Getting_Started/Upgrading_Your_Gear&amp;diff=24576</id>
		<title>Guide:Getting Started/Upgrading Your Gear</title>
		<link rel="alternate" type="text/html" href="https://necessewiki.com/mediawiki/index.php?title=Guide:Getting_Started/Upgrading_Your_Gear&amp;diff=24576"/>
		<updated>2025-12-31T02:47:30Z</updated>

		<summary type="html">&lt;p&gt;Jamesp1989: /* To The Snow Biome */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Upgrading your gear==&lt;br /&gt;
===Making a Forge===&lt;br /&gt;
{{ItemList|compact|&lt;br /&gt;
|Now that we are back on the surface i&#039;m sure you are wanting to reap the rewards of your adventure. go ahead and open the {{Item|Workstation|inline=1}} and craft a {{Item|Forge|inline=1}}. To do this you will need:&amp;lt;br&amp;gt;&lt;br /&gt;
* {{Item|Stone|20}}&lt;br /&gt;
You should have more than enough from your time in the caves. Go ahead and craft it and then place it where you want.&lt;br /&gt;
}}&lt;br /&gt;
===Using your Forge===&lt;br /&gt;
{{ItemList|compact|&lt;br /&gt;
|Now that you have placed your forge you should place your mouse over it and right click. you will get the following window pop up:&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Forgeui.png|500px]]&amp;lt;br&amp;gt;&lt;br /&gt;
you will notice that there is a space for fuel which is required to use the forge. if you followed along with me you should have a bunch of trees around the elders house you can chop down for fuel. place some [[Logs]] in and you are ready to use the forge.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Take your ores that you obtained down in the caves and place them in the two slots on the left inside the forge, Bars will appear on the right hand side of the forge over time till it runs out of ore or fuel&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{tip|tip|It takes 4 ore to make one bar, but if you happened to find any {{Item|Broken Copper Tool|inline =1}} or {{Item|Broken Iron Tool|inline=1}} they can be put in the forge and only costs 1 of them to make the respective bar}}&lt;br /&gt;
&lt;br /&gt;
[[File:Forgerunning.gif|400px]]&lt;br /&gt;
{{tip|tip|If you put 2 different ores in the 2 slots available  it will process the ore on the right first}}&lt;br /&gt;
}}&lt;br /&gt;
===Making an Iron Anvil===&lt;br /&gt;
{{ItemList|compact|&lt;br /&gt;
|&lt;br /&gt;
The next thing we need is an {{Item|Iron Anvil|inline=1}} which is crafted with:&lt;br /&gt;
* {{Item|Iron Bar|5}}&lt;br /&gt;
Once you have made one place it where you like. we are finally ready to craft some [[Equipment]]&lt;br /&gt;
}}&lt;br /&gt;
===Crafting Equipment===&lt;br /&gt;
{{ItemList|compact|&lt;br /&gt;
|&lt;br /&gt;
Head over to your anvil and you should see something like this:&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Anvilui.png|500px]]&amp;lt;br&amp;gt;&lt;br /&gt;
{{tip|tip|there is a tick box down on the bottom left that says &amp;quot;Use nearby inventories&amp;quot; if this is left ticked you can use items from nearby {{Item|Storagebox|inline=1}} instead of having to have the items in your inventory}}}}&lt;br /&gt;
====Armor and Weapons upgrade loop====&lt;br /&gt;
{{ItemList|compact|&lt;br /&gt;
|&lt;br /&gt;
now we need to go back to our {{Item|Forge|inline=1}} with all the ores we have from our first trip down in the caves and smelt everything we have currently. right now you will likely have mostly&lt;br /&gt;
* {{item|Copper Ore|inline=1}} &lt;br /&gt;
* {{item|Iron Ore|inline=1}} &lt;br /&gt;
so smelt them down to bars and then head over to the {{item|Iron Anvil|inline=1}} to make some armor&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
{{tip|tip|Different [[Armor]] have different set perks which are usually geared towards the different fighting styles in the game. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The style you want will usually depend on what your [[Weapon]] of choice is. and we will go more into the what the different styles are good at later.}}&lt;br /&gt;
For now you just want to make the best armor you can so go over and take a look at the anvil.&lt;br /&gt;
&lt;br /&gt;
take a look at the pieces for the armor in the {{item|Iron Anvil|inline=1}} and it will tell you how much of each material you need to craft it. in the case of copper equipment you need:&lt;br /&gt;
}}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Copper Gear&lt;br /&gt;
|-&lt;br /&gt;
! Header text !! Header text&lt;br /&gt;
|-&lt;br /&gt;
| {{item|Copper Bar|inline=1|12}} || {{item|Copper Helmet}}&lt;br /&gt;
|-&lt;br /&gt;
| {{item|Copper Bar|inline=1}|16}} || {{item|Copper Chestplate}}&lt;br /&gt;
|-&lt;br /&gt;
| {{item|Copper Bar|inline=1|8}} || {{item|Copper Boots}}&lt;br /&gt;
|-&lt;br /&gt;
| {{item|Copper Bar|8}}{{item|Any Log|1}} || {{item|Copper Pickaxe}}&lt;br /&gt;
|-&lt;br /&gt;
| {{item|Copper Bar|10}}{{item|Any Log|1}} || {{item|Copper Sword}}&lt;br /&gt;
|}&lt;br /&gt;
{{tip|tip|This is not an extensive list of what you can make with these bars. you can go right to making iron equipment if you have enough resources}}{{ItemList|compact|&lt;br /&gt;
|The idea is to do this with the best equipment you can currently craft and then head back down to the caves and repeat the process of gathering materials&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Once you have a full set of Copper Equipment you should try to move to making Iron equipment and finally Gold equipment. &lt;br /&gt;
}}&lt;br /&gt;
===Enchanting your gear===&lt;br /&gt;
{{ItemList|compact|&lt;br /&gt;
|&lt;br /&gt;
enchanting your gear is very important to give yourself that extra edge. at this point in the game you only have access to enchanting via {{item|Enchanting Scroll|inline=1}} which you will hopefully have found some while down in the caves!&amp;lt;br&amp;gt;&amp;lt;br&amp;gt; Each enchanting scroll is for a specific type of equipment and the description when you hover over the scroll will let you know what it is for. you right click on the scroll you want to use and then drag the piece of equipment you want to enchant into the slot and then press the enchant button.&lt;br /&gt;
{{tip|note|the scroll item is one time use and you will lose it on use but equipment can have its enchantment changed as often as you like}}&lt;br /&gt;
[[File:Enchanting.gif|300px]]&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
In this instance i applied the Sturdy enchantment to my armor giving it an aditional +4 armor.&lt;br /&gt;
}}&lt;br /&gt;
===To The Snow Biome===&lt;br /&gt;
{{tip|tip|This was my build before entering the [[Caves|Snow Caves]].}}&lt;br /&gt;
{{NecesseBuild&lt;br /&gt;
 |trinket1=Fuzzy Dice&lt;br /&gt;
 |trinket2=Zephyr Charm&lt;br /&gt;
 |trinket3=Shine Belt&lt;br /&gt;
 |trinket4=Noble Horseshoe&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 |cosmetic_hat=&lt;br /&gt;
 |cosmetic_chest=&lt;br /&gt;
 |cosmetic_feet=&lt;br /&gt;
 |ability_trinket=Leather Dashers&lt;br /&gt;
&lt;br /&gt;
 |armor_head=Gold Helmet&lt;br /&gt;
 |armor_chest=Gold Chestplate&lt;br /&gt;
 |armor_feet=Gold Boots&lt;br /&gt;
 |mount=Minecart&lt;br /&gt;
 |hotbar1=Gold Pickaxe&lt;br /&gt;
&lt;br /&gt;
 |hotbar2=Wood Axe&lt;br /&gt;
&lt;br /&gt;
 |hotbar3=Gold Sword&lt;br /&gt;
&lt;br /&gt;
 |hotbar4=Gold Bow&lt;br /&gt;
 |hotbar4_qty=40&lt;br /&gt;
&lt;br /&gt;
 |hotbar5=Bread&lt;br /&gt;
 |hotbar5_qty=9&lt;br /&gt;
&lt;br /&gt;
 |hotbar6=Blueberry&lt;br /&gt;
 |hotbar6_qty=12&lt;br /&gt;
&lt;br /&gt;
 |hotbar7=Health Potion&lt;br /&gt;
 |hotbar7_qty=5&lt;br /&gt;
}}&lt;br /&gt;
{{tip|map|there is one more ore above gold that we have access to before the first boss {{item|Frost Shard|inline=1}} which we will be needing to upgrade to but its not found here in the forest caves, so once you have full gold equipment you are ready to visit the snow biome for [[Guide:Getting Started/A Snowy Encounter|a snowy encounter]]}}&lt;/div&gt;</summary>
		<author><name>Jamesp1989</name></author>
	</entry>
	<entry>
		<id>https://necessewiki.com/mediawiki/index.php?title=Guide:Getting_Started&amp;diff=24575</id>
		<title>Guide:Getting Started</title>
		<link rel="alternate" type="text/html" href="https://necessewiki.com/mediawiki/index.php?title=Guide:Getting_Started&amp;diff=24575"/>
		<updated>2025-12-31T02:44:22Z</updated>

		<summary type="html">&lt;p&gt;Jamesp1989: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Getting Started Guide ==&lt;br /&gt;
&lt;br /&gt;
{{tip|tip|Welcome to the wonderful world of &#039;&#039;&#039;Necesse&#039;&#039;&#039;. This game may seem slightly overwhelming but let me reassure you, the basics of this game can be learned quite easily.}}&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Joining A World For The First Time ===&lt;br /&gt;
&lt;br /&gt;
When starting a new world or joining a multiplayer world for the first time you will need to create a new character we call [[The Player]].&lt;br /&gt;
&lt;br /&gt;
{{Tip|note|Your character can be reused across multiple worlds, so don’t worry too much about early choices.}}&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Create player.jpg|300px]]&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Your Starting Location ===&lt;br /&gt;
&lt;br /&gt;
Once you load into the world I suggest you head into the house you spawn by and take a look at the&lt;br /&gt;
[[Guide:Getting_Started/User Interface|User Interface]] and [[Controls]] pages to familiarise yourself with them.&lt;br /&gt;
&lt;br /&gt;
{{Tip|tip|Knowing your controls early will make combat and exploration much easier later on.}}&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:The Elders House.png|500px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;The player&#039;s default spawn point near the Elder&#039;s House.&#039;&#039;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Player Inventory ===&lt;br /&gt;
{{ItemList|compact|The player&#039;s starting inventory includes:&lt;br /&gt;
|&lt;br /&gt;
* {{Item|Wood Axe|inline=1}}&lt;br /&gt;
* {{Item|Wood Sword|inline=1}}&lt;br /&gt;
* {{Item|Crafting Guide|inline=1}}{{Tip|note|These starting tools are enough to begin gathering resources and crafting basic equipment.}}}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:The Players Starting Inventory.png|500px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;Starting inventory.&#039;&#039;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{ItemList|compact|&lt;br /&gt;
|&lt;br /&gt;
== The Elders House ==&lt;br /&gt;
In new worlds, the player spawns in a [[Forest Biome]] next to the house of the [[Elder]], if the corresponding option was selected when creating the world.&lt;br /&gt;
The [[Elder]] is your game guide and [[quests]] giver. He will provide useful and sometimes unique rewards for completing quests, so don&#039;t ignore him.&lt;br /&gt;
&lt;br /&gt;
{{Tip|tip|Completing the Elder’s quests is one of the easiest ways to follow intended [[Guide:Getting_Started/Progression|Progression]]}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{ItemList|compact|&lt;br /&gt;
|&lt;br /&gt;
=== Inside the Elders House ===&lt;br /&gt;
In the Elder&#039;s house, the player will find a {{Item|Workstation|inline=1}} where they can craft their first equipment needed for the further exploration, such as:&lt;br /&gt;
* {{Item|Wood Pickaxe|inline=1}}&lt;br /&gt;
* {{Item|Wood Shovel|inline=1}}&lt;br /&gt;
* {{Item|Wood Boat|inline=1}}&lt;br /&gt;
* {{Item|Torches|inline=1}}&lt;br /&gt;
There is also a {{Item|Spruce Display|inline=1}} which holds:&lt;br /&gt;
* a pair of {{Item|Leather Dashers|inline=1}}&lt;br /&gt;
{{Tip|tip|[[Leather Dashers]] are an [[Trinkets#Ability Trinkets|Ability Trinket]] which allows the player to [[Dashing|Dash]] at the expense of [[Stamina]].&lt;br /&gt;
}}}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{ItemList|compact|&lt;br /&gt;
|&lt;br /&gt;
==== Spawn Points and Beds ====&lt;br /&gt;
The Elder&#039;s {{item|Bed|inline=1}} can be used to set a spawn point inside the house.&amp;lt;br&amp;gt;&lt;br /&gt;
This is the place the player will return to when they die.&lt;br /&gt;
{{tip|note|You will be able to craft your own beds later.Beds can be used to skip between day and night if all players are in bed. we will go more into the day and night cycle shortly}}}}&lt;br /&gt;
{{ItemList|compact|&lt;br /&gt;
|&lt;br /&gt;
==== The Elder&#039;s Storagebox ====&lt;br /&gt;
There is a {{Item|Storagebox|inline=1}} in the elders house that the player can take items from which contains:&lt;br /&gt;
* {{Item|Village Map|inline=1}}&lt;br /&gt;
* {{Item|Dungeon Map|inline=1}}&lt;br /&gt;
* {{Item|Bread|inline=1}}&lt;br /&gt;
* {{Item|Health Potion|inline=1}}&lt;br /&gt;
* {{Item|Settlement Flag|inline=1}}&lt;br /&gt;
{{Tip|note|A [[Settlement Flag]] is used to start a [[Settlements|settlement]].  &lt;br /&gt;
The flag can be placed on any [[terrain]] [[Tiles|tile]] outside or inside the house. Go ahead and do this now as we will need it placed later to take a quest from the elder, We will cover [[Guide:Getting_Started/Settlements|Settlements]] in more detail later in the guide}}}}&lt;br /&gt;
{{ItemList|compact|&lt;br /&gt;
|&lt;br /&gt;
==== Cave Ladder ====&lt;br /&gt;
{{Tip|warning|The elders house also has a {{Item|Cave Ladder|inline=1}} to go down into the [[Caves]] but we arent quite ready for that yet.}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{ItemList|compact|&lt;br /&gt;
|&lt;br /&gt;
=== Outside the Elders House ===&lt;br /&gt;
Outside the house is a {{Item|Roasting Station|inline=1}} on top of a {{Item|Campfire|inline=1}} which you can use to cook raw meat from:&lt;br /&gt;
* {{Item|Cow|inline=1}}&lt;br /&gt;
* {{Item|Sheep|inline=1}} &lt;br /&gt;
and other [[Animals]]&lt;br /&gt;
&lt;br /&gt;
{{Tip|note|It&#039;s best not to kill the animals near your spawn as you can use them later for [[Animals#Taming|Taming]], [[Animals#Breeding|Breeding]] and [[Animals#Harvesting|Harvesting]].}}}}&lt;br /&gt;
&lt;br /&gt;
=Exploring the World=&lt;br /&gt;
===Day And Night Cycle===&lt;br /&gt;
{{tip|note|The world has a day and night cycle. in the forest nothing hostile will spawn during the day but [[Zombie]]s come out at night so be sure to take shelter or be prepared to fight }}&lt;br /&gt;
&lt;br /&gt;
== Obtaining Mining Gear ==&lt;br /&gt;
{{ItemList|compact|Head outside of the [[elder]]s house and chop down some [[Trees]].&lt;br /&gt;
|&lt;br /&gt;
In the forest it will be either:&lt;br /&gt;
* {{item|Oak Tree|inline=1|size=32px}}&lt;br /&gt;
* {{item|Spruce Tree|inline=1|size=32px}}&lt;br /&gt;
{{tip|tip|You can chop trees down with the {{item|Wood Axe|inline=1}} that came in your starting inventory and collect the [[Logs]] and [[Saplings]] that drop. &lt;br /&gt;
&lt;br /&gt;
You should cut down more than you need so that you can use the extra logs to craft more torches and replant the saplings near the elders house to grow over time.&lt;br /&gt;
}}}}&lt;br /&gt;
{{ItemList|compact|&lt;br /&gt;
|&lt;br /&gt;
Before We head down to the [[Caves]] we need at least: &lt;br /&gt;
* {{item|Oak Log|inline=1|size=32px|2}} to make a {{item|Wood Pickaxe|inline=1}} &lt;br /&gt;
* 10 logs and 10 saplings to make {{item|Torch|inline=1|size=32px|40}}&lt;br /&gt;
{{Tip|warning|Torches are essential in caves — darkness hides enemies and hazards.}}}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{ItemList|compact|Once you have all of these head over to the {{item|Workstation|inline=1}} inside the [[Elder]]s house and craft:&lt;br /&gt;
|&lt;br /&gt;
* {{item|Wood Pickaxe|inline=1}}&lt;br /&gt;
* {{item|Torch|inline=1|40}}&lt;br /&gt;
}}&lt;br /&gt;
= Food =&lt;br /&gt;
=== Food Spoilage ===&lt;br /&gt;
&lt;br /&gt;
{{tip|tip|&lt;br /&gt;
Food in your backpack and regular {{Item|Storagebox|inline=1}} will spoil over time and different foods have their own spoil times. once this time reaches 0 it becomes {{item|Spoiled Food|inline=1}} which has its own uses which we will get into later&lt;br /&gt;
}}&lt;br /&gt;
=== Food Buffs ===&lt;br /&gt;
{{ItemList|compact|&lt;br /&gt;
|&lt;br /&gt;
{{tip|tip|&amp;lt;br&amp;gt;Food items are very important in Necesse and not just to stave off [[Guide:Getting_Started/User_Interface#Hunger|hunger]]:&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;not only do different food items restore your hunger by differing amounts they also all give the player buffs dependant on the food item consumed.&amp;lt;br&amp;gt; &lt;br /&gt;
Food items can be separated into Raw, Fine and Gourmet with the buffs received getting better the higher the quality of food is, but we will go into that later }}{{tip|warning|you can only have one food buff at a time and consuming another will remove the previous buff instantly}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{ItemList|compact|&lt;br /&gt;
|&lt;br /&gt;
I wont go into a great deal about the different food or food buffs right now but I will cover the first few you are likely to encounter:&lt;br /&gt;
==[[Simple Food]]==&lt;br /&gt;
===Fruits ===&lt;br /&gt;
These are classed as simple raw foods that have a positive buff when eaten:&lt;br /&gt;
* {{Item|Apple|inline=1|+2% Movement Speed}}&lt;br /&gt;
* {{Item|Blueberry|inline=1|+2% Crit Chance}}&lt;br /&gt;
=== Raw Meat ===&lt;br /&gt;
These are raw meats. you shouldn&#039;t eat these without [[Guide:Getting_Started#Outside the Elders House|cooking them]] otherwise you will take 10 damage&lt;br /&gt;
* {{Item|Beef|inline=1|-10 Health}}(becomes {{Item|Steak|inline=1}} when cooked)&lt;br /&gt;
* {{Item|Raw Mutton|inline=1|-10 Health}}(becomes {{Item|Roasted Mutton|inline=1}} when cooked)&lt;br /&gt;
== [[Fine Food]]s ==&lt;br /&gt;
* {{Item|Steak|inline=1|+2% Damage}}&lt;br /&gt;
* {{Item|Roasted Mutton|inline=1|+2% Crit Chance}}&lt;br /&gt;
* {{Item|Bread|inline=1|+20 Max Health}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
= Final Preparations =&lt;br /&gt;
&lt;br /&gt;
{{ItemList|compact|If you haven&#039;t already make sure you grab:&lt;br /&gt;
|&lt;br /&gt;
* {{item|Bread|inline=1}}&lt;br /&gt;
* {{item|Health Potion|inline=1}} &lt;br /&gt;
&lt;br /&gt;
from the chest or: &lt;br /&gt;
* find some {{item|Blueberry|inline=1}} from {{item|Blueberry Bush|inline=1|size=32px}} in the surrounding forest.&lt;br /&gt;
{{Tip|tip|If you come across any {{item|Blueberry Bush|inline=1|size=32px}} you should break these and place them near the elders house as an early source of food.&lt;br /&gt;
&lt;br /&gt;
Carrying food and healing items greatly increases your survival chances underground.}}}}&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Your inventory should look a little like this:&lt;br /&gt;
&lt;br /&gt;
{{NecesseBuild&lt;br /&gt;
 |cosmetic_feet=Shoes&lt;br /&gt;
 |ability_trinket=Leather Dashers&lt;br /&gt;
&lt;br /&gt;
 |hotbar1=Wood Pickaxe&lt;br /&gt;
 |hotbar2=Wood Axe&lt;br /&gt;
 |hotbar3=Wood Sword&lt;br /&gt;
&lt;br /&gt;
 |hotbar4=Torch&lt;br /&gt;
 |hotbar4_qty=40&lt;br /&gt;
&lt;br /&gt;
 |hotbar5=Bread&lt;br /&gt;
 |hotbar5_qty=9&lt;br /&gt;
&lt;br /&gt;
 |hotbar6=Blueberry&lt;br /&gt;
 |hotbar6_qty=12&lt;br /&gt;
&lt;br /&gt;
 |hotbar7=Health Potion&lt;br /&gt;
 |hotbar7_qty=5&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Down We Go ===&lt;br /&gt;
&lt;br /&gt;
{{Tip|map|If you feel unsure, you can always gather more supplies before entering the caves.&amp;lt;br&amp;gt;&lt;br /&gt;
Head over to the cave ladder for&lt;br /&gt;
[[Guide:Getting_Started/Your_First_Cave|Your First Cave]]&lt;br /&gt;
when you feel comfortable you have everything you need.}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Guides]]&lt;/div&gt;</summary>
		<author><name>Jamesp1989</name></author>
	</entry>
	<entry>
		<id>https://necessewiki.com/mediawiki/index.php?title=Guide:Getting_Started&amp;diff=24574</id>
		<title>Guide:Getting Started</title>
		<link rel="alternate" type="text/html" href="https://necessewiki.com/mediawiki/index.php?title=Guide:Getting_Started&amp;diff=24574"/>
		<updated>2025-12-31T02:37:02Z</updated>

		<summary type="html">&lt;p&gt;Jamesp1989: /* The Elders House */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Getting Started Guide =&lt;br /&gt;
&lt;br /&gt;
{{tip|tip|Welcome to the wonderful world of &#039;&#039;&#039;Necesse&#039;&#039;&#039;. This game may seem slightly overwhelming but let me reassure you, the basics of this game can be learned quite easily.}}&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Joining A World For The First Time ==&lt;br /&gt;
&lt;br /&gt;
When starting a new world or joining a multiplayer world for the first time you will need to create a new character we call [[The Player]].&lt;br /&gt;
&lt;br /&gt;
{{Tip|note|Your character can be reused across multiple worlds, so don’t worry too much about early choices.}}&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Create player.jpg|300px]]&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Your Starting Location ==&lt;br /&gt;
&lt;br /&gt;
Once you load into the world I suggest you head into the house you spawn by and take a look at the&lt;br /&gt;
[[Guide:Getting_Started/User Interface|User Interface]] and [[Controls]] pages to familiarise yourself with them.&lt;br /&gt;
&lt;br /&gt;
{{Tip|tip|Knowing your controls early will make combat and exploration much easier later on.}}&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:The Elders House.png|500px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;The player&#039;s default spawn point near the Elder&#039;s House.&#039;&#039;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Player Inventory ==&lt;br /&gt;
{{ItemList|compact|The player&#039;s starting inventory includes:&lt;br /&gt;
|&lt;br /&gt;
* {{Item|Wood Axe|inline=1}}&lt;br /&gt;
* {{Item|Wood Sword|inline=1}}&lt;br /&gt;
* {{Item|Crafting Guide|inline=1}}{{Tip|note|These starting tools are enough to begin gathering resources and crafting basic equipment.}}}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:The Players Starting Inventory.png|500px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;Starting inventory.&#039;&#039;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{ItemList|compact|&lt;br /&gt;
|&lt;br /&gt;
== The Elders House ==&lt;br /&gt;
In new worlds, the player spawns in a [[Forest Biome]] next to the house of the [[Elder]], if the corresponding option was selected when creating the world.&lt;br /&gt;
The [[Elder]] is your game guide and [[quests]] giver. He will provide useful and sometimes unique rewards for completing quests, so don&#039;t ignore him.&lt;br /&gt;
&lt;br /&gt;
{{Tip|tip|Completing the Elder’s quests is one of the easiest ways to follow intended [[Guide:Getting_Started/Progression|Progression]]}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{ItemList|compact|&lt;br /&gt;
|&lt;br /&gt;
=== Inside the Elders House ===&lt;br /&gt;
In the Elder&#039;s house, the player will find a {{Item|Workstation|inline=1}} where they can craft their first equipment needed for the further exploration, such as:&lt;br /&gt;
* {{Item|Wood Pickaxe|inline=1}}&lt;br /&gt;
* {{Item|Wood Shovel|inline=1}}&lt;br /&gt;
* {{Item|Wood Boat|inline=1}}&lt;br /&gt;
* {{Item|Torches|inline=1}}&lt;br /&gt;
There is also a {{Item|Spruce Display|inline=1}} which holds:&lt;br /&gt;
* a pair of {{Item|Leather Dashers|inline=1}}&lt;br /&gt;
{{Tip|tip|[[Leather Dashers]] are an [[Trinkets#Ability Trinkets|Ability Trinket]] which allows the player to [[Dashing|Dash]] at the expense of [[Stamina]].&lt;br /&gt;
}}}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{ItemList|compact|&lt;br /&gt;
|&lt;br /&gt;
==== Spawn Points and Beds ====&lt;br /&gt;
The Elder&#039;s {{item|Bed|inline=1}} can be used to set a spawn point inside the house.&amp;lt;br&amp;gt;&lt;br /&gt;
This is the place the player will return to when they die.&lt;br /&gt;
{{tip|note|You will be able to craft your own beds later.Beds can be used to skip between day and night if all players are in bed. we will go more into the day and night cycle shortly}}}}&lt;br /&gt;
{{ItemList|compact|&lt;br /&gt;
|&lt;br /&gt;
==== The Elder&#039;s Storagebox ====&lt;br /&gt;
There is a {{Item|Storagebox|inline=1}} in the elders house that the player can take items from which contains:&lt;br /&gt;
* {{Item|Village Map|inline=1}}&lt;br /&gt;
* {{Item|Dungeon Map|inline=1}}&lt;br /&gt;
* {{Item|Bread|inline=1}}&lt;br /&gt;
* {{Item|Health Potion|inline=1}}&lt;br /&gt;
* {{Item|Settlement Flag|inline=1}}&lt;br /&gt;
{{Tip|note|A [[Settlement Flag]] is used to start a [[Settlements|settlement]].  &lt;br /&gt;
The flag can be placed on any [[terrain]] [[Tiles|tile]] outside or inside the house. Go ahead and do this now as we will need it placed later to take a quest from the elder, We will cover [[Guide:Getting_Started/Settlements|Settlements]] in more detail later in the guide}}}}&lt;br /&gt;
{{ItemList|compact|&lt;br /&gt;
|&lt;br /&gt;
==== Cave Ladder ====&lt;br /&gt;
{{Tip|warning|The elders house also has a {{Item|Cave Ladder|inline=1}} to go down into the [[Caves]] but we arent quite ready for that yet.}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{ItemList|compact|&lt;br /&gt;
|&lt;br /&gt;
=== Outside the Elders House ===&lt;br /&gt;
Outside the house is a {{Item|Roasting Station|inline=1}} on top of a {{Item|Campfire|inline=1}} which you can use to cook raw meat from:&lt;br /&gt;
* {{Item|Cow|inline=1}}&lt;br /&gt;
* {{Item|Sheep|inline=1}} &lt;br /&gt;
and other [[Animals]]&lt;br /&gt;
&lt;br /&gt;
{{Tip|note|It&#039;s best not to kill the animals near your spawn as you can use them later for [[Animals#Taming|Taming]], [[Animals#Breeding|Breeding]] and [[Animals#Harvesting|Harvesting]].}}}}&lt;br /&gt;
&lt;br /&gt;
=Exploring the World=&lt;br /&gt;
===Day And Night Cycle===&lt;br /&gt;
{{tip|note|The world has a day and night cycle. in the forest nothing hostile will spawn during the day but [[Zombie]]s come out at night so be sure to take shelter or be prepared to fight }}&lt;br /&gt;
&lt;br /&gt;
== Obtaining Mining Gear ==&lt;br /&gt;
{{ItemList|compact|Head outside of the [[elder]]s house and chop down some [[Trees]].&lt;br /&gt;
|&lt;br /&gt;
In the forest it will be either:&lt;br /&gt;
* {{item|Oak Tree|inline=1|size=32px}}&lt;br /&gt;
* {{item|Spruce Tree|inline=1|size=32px}}&lt;br /&gt;
{{tip|tip|You can chop trees down with the {{item|Wood Axe|inline=1}} that came in your starting inventory and collect the [[Logs]] and [[Saplings]] that drop. &lt;br /&gt;
&lt;br /&gt;
You should cut down more than you need so that you can use the extra logs to craft more torches and replant the saplings near the elders house to grow over time.&lt;br /&gt;
}}}}&lt;br /&gt;
{{ItemList|compact|&lt;br /&gt;
|&lt;br /&gt;
Before We head down to the [[Caves]] we need at least: &lt;br /&gt;
* {{item|Oak Log|inline=1|size=32px|2}} to make a {{item|Wood Pickaxe|inline=1}} &lt;br /&gt;
* 10 logs and 10 saplings to make {{item|Torch|inline=1|size=32px|40}}&lt;br /&gt;
{{Tip|warning|Torches are essential in caves — darkness hides enemies and hazards.}}}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{ItemList|compact|Once you have all of these head over to the {{item|Workstation|inline=1}} inside the [[Elder]]s house and craft:&lt;br /&gt;
|&lt;br /&gt;
* {{item|Wood Pickaxe|inline=1}}&lt;br /&gt;
* {{item|Torch|inline=1|40}}&lt;br /&gt;
}}&lt;br /&gt;
= Food =&lt;br /&gt;
=== Food Spoilage ===&lt;br /&gt;
&lt;br /&gt;
{{tip|tip|&lt;br /&gt;
Food in your backpack and regular {{Item|Storagebox|inline=1}} will spoil over time and different foods have their own spoil times. once this time reaches 0 it becomes {{item|Spoiled Food|inline=1}} which has its own uses which we will get into later&lt;br /&gt;
}}&lt;br /&gt;
=== Food Buffs ===&lt;br /&gt;
{{ItemList|compact|&lt;br /&gt;
|&lt;br /&gt;
{{tip|tip|&amp;lt;br&amp;gt;Food items are very important in Necesse and not just to stave off [[Guide:Getting_Started/User_Interface#Hunger|hunger]]:&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;not only do different food items restore your hunger by differing amounts they also all give the player buffs dependant on the food item consumed.&amp;lt;br&amp;gt; &lt;br /&gt;
Food items can be separated into Raw, Fine and Gourmet with the buffs received getting better the higher the quality of food is, but we will go into that later }}{{tip|warning|you can only have one food buff at a time and consuming another will remove the previous buff instantly}}&lt;br /&gt;
&lt;br /&gt;
I wont go into a great deal about the different food or food buffs right now but I will cover the first few you are likely to encounter:&lt;br /&gt;
{{ItemList|compact|&lt;br /&gt;
|&lt;br /&gt;
==[[Simple Food]]==&lt;br /&gt;
===Fruits ===&lt;br /&gt;
These are classed as simple raw foods that have a positive buff when eaten:&lt;br /&gt;
* {{Item|Apple|inline=1|+2% Movement Speed}}&lt;br /&gt;
* {{Item|Blueberry|inline=1|+2% Crit Chance}}&lt;br /&gt;
=== Raw Meat ===&lt;br /&gt;
These are raw meats. you shouldn&#039;t eat these without [[Guide:Getting_Started#Outside the Elders House|cooking them]] otherwise you will take 10 damage&lt;br /&gt;
* {{Item|Beef|inline=1|-10 Health}}(becomes {{Item|Steak|inline=1}} when cooked)&lt;br /&gt;
* {{Item|Raw Mutton|inline=1|-10 Health}}(becomes {{Item|Roasted Mutton|inline=1}} when cooked)&lt;br /&gt;
== [[Fine Food]]s ==&lt;br /&gt;
* {{Item|Steak|inline=1|+2% Damage}}&lt;br /&gt;
* {{Item|Roasted Mutton|inline=1|+2% Crit Chance}}&lt;br /&gt;
* {{Item|Bread|inline=1|+20 Max Health}}&lt;br /&gt;
}}}}&lt;br /&gt;
&lt;br /&gt;
= Final Preparations =&lt;br /&gt;
&lt;br /&gt;
{{ItemList|compact|If you haven&#039;t already make sure you grab:&lt;br /&gt;
|&lt;br /&gt;
* {{item|Bread|inline=1}}&lt;br /&gt;
* {{item|Health Potion|inline=1}} &lt;br /&gt;
&lt;br /&gt;
from the chest or: &lt;br /&gt;
* find some {{item|Blueberry|inline=1}} from {{item|Blueberry Bush|inline=1|size=32px}} in the surrounding forest.&lt;br /&gt;
{{Tip|tip|If you come across any {{item|Blueberry Bush|inline=1|size=32px}} you should break these and place them near the elders house as an early source of food.&lt;br /&gt;
&lt;br /&gt;
Carrying food and healing items greatly increases your survival chances underground.}}}}&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Your inventory should look a little like this:&lt;br /&gt;
&lt;br /&gt;
{{NecesseBuild&lt;br /&gt;
 |cosmetic_feet=Shoes&lt;br /&gt;
 |ability_trinket=Leather Dashers&lt;br /&gt;
&lt;br /&gt;
 |hotbar1=Wood Pickaxe&lt;br /&gt;
 |hotbar2=Wood Axe&lt;br /&gt;
 |hotbar3=Wood Sword&lt;br /&gt;
&lt;br /&gt;
 |hotbar4=Torch&lt;br /&gt;
 |hotbar4_qty=40&lt;br /&gt;
&lt;br /&gt;
 |hotbar5=Bread&lt;br /&gt;
 |hotbar5_qty=9&lt;br /&gt;
&lt;br /&gt;
 |hotbar6=Blueberry&lt;br /&gt;
 |hotbar6_qty=12&lt;br /&gt;
&lt;br /&gt;
 |hotbar7=Health Potion&lt;br /&gt;
 |hotbar7_qty=5&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Down We Go ===&lt;br /&gt;
&lt;br /&gt;
{{Tip|map|If you feel unsure, you can always gather more supplies before entering the caves.&amp;lt;br&amp;gt;&lt;br /&gt;
Head over to the cave ladder for&lt;br /&gt;
[[Guide:Getting_Started/Your_First_Cave|Your First Cave]]&lt;br /&gt;
when you feel comfortable you have everything you need.}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Guides]]&lt;/div&gt;</summary>
		<author><name>Jamesp1989</name></author>
	</entry>
</feed>