Modding

Modding é o ato de modificar, adicionar ou remover conteúdo e recursos. Os mods são criados pela comunidade e compartilhados através da Oficina da Steam. Eles podem ser qualquer coisa como adicionar mais itens e monstros, adicionar um novo idioma, alterar as texturas do jogo, adicionar novos recursos, ajustar o equilíbrio e muito mais.

Mods de Necesse são criados usando a linguagem de programação Java.

### Adendo

Para preservar informação, algumas partes não foram traduzidas.

## Instalando e usando mods

### Oficina da Steam

Os modders geralmente compartilham seus mods na Oficina da Steam (ou Workshop). Se você se inscrever em um mod, na próxima vez que iniciar o jogo, um botão de mods aparecerá no menu principal. Neste menu você pode ver os mods que instalou, alterar sua ordem de carregamento, ativá-los ou desativá-los.

### Servidores dedicados e mods locais

Para que servidores dedicados tenham mods, eles devem encontrar e baixar o arquivo *mod jar*. Muitos modders fornecem links de onde eles podem ser baixados na página do Oficina dos mods. Depois de obter o arquivo jar, você deve colocá-lo dentro de uma pasta mods, dependendo do seu sistema.

Se a pasta não existir no seu sistema, você mesmo poderá criar uma.
**Adendo: APENAS o arquivo jar é necessário para que o mod esteja ativo, o restante dos arquivos dentro do mod de exemplo são para tarefas *gradle* para ajudar a tornar o teste de mods mais fácil**

* **Windows:** %APPDATA%/Necesse/mods/
* **Linux:** ~/.config/Necesse/mods/
* **Mac:** ~/Library/Application Support/Necesse/mods/

## Pacotes de Recursos/Texturas

Os pacotes de textura não são oficialmente suportados, exceto através do sistema de modding. Porém, ainda é possível substituir texturas existentes dentro do jogo. Para fazer isso, siga as etapas:

1. Instale as texturas oficiais, encontradas no Servidor Oficial do Discord, em uma mensagem fixada dentro do canal da wiki.
2. Encontre o diretório de instalação do jogo. Você pode fazer isso clicando com o botão direito no jogo na seu Biblioteca da Steam -> Gerenciar-> Explorar arquivos locais.
3. Extraia os arquivos de textura para "<Necesse install directory>/res"(Diretório de instalação de Necesse). Se a pasta “res” não existir, você mesmo deverá criá-la.

Na próxima vez que você iniciar o jogo, as texturas serão carregadas a partir dos arquivos extraídos. Isso significa que você pode editar ou substituir qualquer um dos arquivos e ele será carregado.

## Criando mods

Os mods necessários são criados usando a linguagem de programação Java. Esta página não é para você aprender Java, já existem muitos tutoriais e recursos sobre isso na internet.

Os mods são armazenados dentro de um arquivo jar para o jogo carregar durante o tempo de execução(runtime). Ao modificar, é uma boa ideia ter um descompilador (incluído na maioria dos IDEs). O código-fonte ainda não foi liberado (se algum dia for) e muitos tópicos ainda não foram explicados detalhadamente. Isso significa que muitas vezes você precisa descompilar classes e verificar como elas são feitas no jogo principal.

O Servidor Oficial do Discord tem um canal dedicado a modding onde você pode fazer perguntas, obter ajuda e solicitar novos recursos de modding para o jogo e todas as outras coisas necessárias para modding.

### Novo na v. 0.21.27

*Se você está apenas começando com modding, pode pular esta seção.*

Na versão 0.21.27 e posteriores, o jogo mudou o ambiente de execução(runtime environment) Java que usava. Se você tentar iniciar o jogo com o ambiente de execução antigo, poderá encontrar travamentos ou outros problemas. Você pode baixar o runtime atualmente em uso aqui. Para ajudar na compatibilidade, o nível de linguagem (language level) ainda é a versão 8. No IntelliJ, você pode alterar seu JDK e o nível de linguagem acessando Arquivo -> Estrutura do Projeto... -> Projeto(File -> Project Structure... -> Project). Certifique-se de que o Gradle também esteja usando o JDK correto acessando Arquivo -> Configurações -> Construir, Execução e Implantação -> Ferramentas de Construção -> Gradle -> Gradle JVM(File -> Settings -> Build, Execution and Deployment -> Build Tools -> Gradle -> Gradle JVM). O projeto de exemplo foi atualizado para usar esta nova versão Java e Gradle.

### Primeiros passos e projeto de exemplo

Para começar com modding, existe um **projeto de exemplo oficial que você pode baixar, encontrado no Github.** Ele inclui coisas básicas como adicionar itens, blocos, objetos , monstros, receitas e muito mais. Também inclui ferramentas de construção usando Gradle para compilar e estruturar facilmente seu mod para que possa ser lido e carregado pelo jogo, e também ferramentas de desenvolvimento como carregar seu mod em desenvolvimento, para que você possa carregá-lo na Oficina da Steam quando completo.

### Ferramentas de modding

* Um Ambiente de Desenvolvimento Integrado (IDE). Por exemplo Intellij IDEA Community, que é gratuito.
* Um kit de desenvolvimento Java. O jogo é construído usando Adoptium Java17, que você pode encontrar aqui, mas por motivos de compatibilidade ainda está usando apenas o nível de linguagem 8. Se você estiver usando o IDE Intellij , isso não é necessário porque um JDK já está incluído nele. Certifique-se de usar o nível de linguagem 8 acessando Arquivo -> Estrutura do projeto... -> Nível de linguagem (File -> Project Structure... -> Language Level).
* Uma ferramenta de edição de imagens, como editores de pixel art Asesprite ou Pyxel Edit.
* Uma ferramenta de edição de áudio, como Audacity ou REAPER.

### Setting up

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 *build.gradle* file with the correct mod info and the games install directory. Once done, it will prompt you to refresh the project.

### Running and testing your mod

 Arquivo:Mod runClient Task.png  To run your in-development mod, you will need to launch the game with *-mod <folder path with your mod jar>* option. This is already done for you if you are using the example project and run the *runClient* 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.

#### Testing multiplayer

To test multiplayer, you can run one client with the *runClient* Gradle task, and another with the *runDevClient* 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 "localhost" 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.

It'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 *runServer* 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 "localhost" as IP the address.

### Mod info file

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 *build.gradle* file.

Every mod must have a *mod.info* file in their jar's top path. The file structure is custom, but very similar to JSON. It's used throughout the game's saved files. The file must have these fields:

* **id** - The unique ID of your mod. Must be all lowercase and cannot use special characters.
* **name** - The display name of your mod.
* **version** - The version of your mod.
* **gameVersion** - The target game version of your mod.
* **description** - A short description of your mod.
* **author** - Your name
* **dependencies** (optional) - Your mods dependencies are formatted in their IDs and array. Like this: [exammple.mod, other.mod]
* **optionalDependecies** (optional) - Your mods optional dependencies. They are used together with your dependencies to automatically make a load order for mods.
* **clientside** (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.

**Important notes about your mod.info file:**

1. Your id should be unique to the mod and never change between versions. A good example for id is "<your name>.<mod name>".
2. 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.

Example of a mod.info file:

```
{
   id = fair.examplemod,
   name = Example Mod,
   version = 1.0,
   gameVersion = 0.21.23,
   description = Just an example mod,
   author = Fair
}

```

### Mod entry class

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's where your mod starts.

**Important notes about your @ModEntry class:**

1. Make sure your mod only has one @ModEntry annotation. The game will stop looking for more when found one.
2. Make sure the class does NOT have a constructor.

Example for your mod entry class:

```
import necesse.engine.modLoader.annotations.ModEntry;

@ModEntry
public class ExampleMod {

    public void init() {
        System.out.println("Hello world from my example mod!");
    }

}

```
The game will look for specific methods within your @ModEntry class. Here's a description of them:

#### public void preInit()

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't use it.

#### public void init()

This method is called after the core game has been loaded. Here you should register your own tiles, objects, items, mobs and so on.

The general order in which you should register your mod objects to avoid issues are (not forced):

1. Tiles
2. Objects
3. Biomes
4. Buffs
5. Global ingredients
6. Recipe techs
7. Items
8. Enchantments
9. Mobs
10. Pickup entities and projectiles
11. Level, world events, level data and settlers
12. Containers
13. World generators
14. Packets
15. Quests
16. Other

#### public void initResources()

This method is called only on the client and should load any extra resources your mod uses that the game doesn't automatically load.

The resources will be loaded from a resource folder. You can read more about this in a later section.

Example: Assign a texture:

`GameTexture texture = GameTexture.fromFile("path/to/file")`

If you have a texture at resources/texture.png you can load it using `GameTexture.fromFile("texture")`

All sound (.ogg) files need to be placed in resources/sound folder and can be loaded using

`GameSound.fromFile("path/to/file")`

For example, a song placed in resources/sound/music/MySong.ogg would be loaded as `GameSound.fromFile("music/MySong")`, ommiting resources/sound

For information on music paths to override music, look at `MusicRegistry.registerCore`

#### public void postInit()

This method is called after the game is done loading all its core, mods and resources.

This is where you should register recipes, create or modify loot tables and spawn tables and register chat commands.

#### public void dispose()

This methodd is called when the game closes. If you have anything that needs to be disposed, that the game doesn't already dispose on it's own, do it here.

Things like textured loaded using `GameTexture.fromFile(...)` and sounds are automatically disposed.

### Building your mod

If you are using the example project, a lot of this is already done for you. Simply run the *buildModJar* Gradle task, and it will generate the jar inside the ./build/jar folder.

For the game to recognize your jar, it has to follow a specific structure:

ExampleMod.jar
↳ resources
↳ Your resource files
↳ Java class files
↳ mod.info file
### Uploading your mod

 Arquivo:Upload mod.png  To upload your mod to the Steam workshop, a few conditions have to be met:

* Must be enabled
* Must have a preview.png file in the resources folder
* Must be loaded through the -mod launch option (this is done automatically in the example project when running the *runClient* Gradle task. You can find more info about this under the beginning of the setting up section).

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.

### Localization

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.

You can also see how the localization file is structured inside the example mod project.

#### The file structure

The file is divided up into categories and keys. If your item has the localization *item.exampleitem*, it means that it's under the *item* category and has the key *exampleitem*.

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's an example:

```
[mycategory]
mykey=Text
otherkey=Other text

[newcategory]
differentkey=Different text

[item]
exampleitem=Example item

```
Translations can have replacements that can be done in runtime. To add a replacement key in your translation, add a <key> somewhere. The key can be anything like <name>, <number> etc. Example: `mobhealth=Mob health: <health>`

#### Using a translation inside the game

`Localization.translate(category, key)` `Localization.translate(category, key, replaceKey1, replaceString1, replaceKey2, replaceString2, ...)`

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: `new LocalMessage(category, key, replaceKey1, replaceString1, replaceKey2, replaceString2, ...)`

If you don't want to use a translation, you can also just give it a static string with `new StaticMessage(string...)`

### Resources

For the game to load your resources, they have to placed inside a resources folder in your mod jar.

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.

This also means that your resource files can get overwritten by other mods, so try and keep your file names unique.

Resource loading happens automatically for any files in the resources folder. But some things will look at specific subfolders to load their textures. Examples:

* **Items** - items/<item stringiD>
* **Buffs** - buffs/<buff stringiD>
* **Biomes** - biomes/<biome stringiD>
* **Projectiles** - projectiles/<projectile stringiD>

## More documentation

Until more documentation gets migrated and added to this wiki, you can use the old documentation here: Published Google docs file

## Accessing Necesse Java files

 Arquivo:Decompile1.png   Arquivo:Decompile2.png   Arquivo:Decompile3.png   Arquivo:Decompile4.png  using the IDE mentioned in Modding Tools, you can decompile java files and take a peek at the core game values.

**Note: Java may need to be installed for this process**

You probably need to have Java installed.(external links not allowed)

Download and install the Windows x64 .msi file

**Rough Transcript from Discord User Snoobinoob, to be refined:**

Open up IntelliJ IDEA and create a new Java project wherever

File > New > Project...

Can leave all settings as is

Once the project is created, open up the project structure

File > Project Structure... (Ctrl+Alt+Shift+S)

select "Modules" from the left navigaiton pane

Click the dependencies tab on the top-right-ish (Decompile1)

Click the + icon to add a new module and choose "JARs or Directories" (Decompile2)

Browse to the steam files location of Necesse.jar

Should be something like: C:\Program Files (x86)\Steam\steamapps\common\Necesse\Necesse.jar

Should see this (or similar) after clicking the +, choosing JARs or Directories, and browsing to the Necesse.jar location (Decompile3)

Click OK, and you should now see Necesse.jar in the list of dependencies in the previous Modules window

Click OK again to close the project structure window

Necesse.jar should now be visible in External Libraries (Decompile4)

Everything should now be set up, so you can search via the Navigate > Search Everywhere menu option

Exactly what to search is up to you, and not always the most obvious