Pour les autres mods

Douze points sont ouverts, et rien de ce que le mod livre n'est un cas particulier qu'il se garderait : chaque palier, module, cellule, ordre de tri et ligne d'infobulle passe par les mêmes appels que les vôtres.

Les douze points, et ce que chacun ajoute
PointCe qu'il ajoute
registerTierun coffre, avec son bloc, ses rangées et ses colonnes
registerModuleun module de capacité, pointé sur une étiquette d'objet
registerRowModuleun module qui achète des rangées, là où l'autre achète de la pile
registerModuleSlotune cellule sur la languette, qui grandit avec
onTierRegisteredun appel à chaque palier enregistré après le vôtre
CrateLayoutCallbackle dernier mot sur les rangées par page et le nombre de pages
CrateCapacityCallbackle dernier mot sur ce qu'une case tient, objet par objet
ConfigSchema.registerHoldervos propres options, dans le même fichier de réglages
ConfigBounds.registerGroupla plage dans laquelle chacune est ramenée
registerSortOrderun bouton de tri, avec son icône et son comparateur
CrateScreenCallbackun widget sur l'écran du coffre
CrateTooltipCallbackune ligne dans l'infobulle d'une case de coffre

Le point d'entrée

DeepCrateAddon a deux méthodes, qui sont deux passes du démarrage du mod. onDeepCrateConfig() tourne avant la lecture du fichier de réglages, onDeepCrateInit() une fois les onze paliers livrés en place et avant que quoi que ce soit ne lise un registre. Un module pointe sur une étiquette d'objet plutôt que sur un objet précis, donc ajouter le vôtre à deepcrate:module_512 en fait un module sans une ligne de code.

Un addon en entier

Voici tout ce qu'il faut pour ajouter un coffre et un module de capacité, sans mixin et sans rien demander. Le point d'entrée se déclare dans votre propre fabric.mod.json :

fabric.mod.json"entrypoints": {
  "deepcrate": ["com.example.slatecrate.SlateCrateAddon"]
}

Votre script de build a besoin de Fabric API et du jar de DeepCrate sur le même classpath de compilation, tous deux en modImplementation plutôt qu'en modRuntimeOnly : les évènements du tableau ci-dessus sont des objets Event de Fabric qui ne compilent pas sans Fabric API, et atteindre Blocks.register pour le bloc d'un palier demande l'access widener propre à Fabric API, donc une déclaration en exécution seule échoue avant même que l'addon compile.

build.gradle.ktsdependencies {
    modImplementation("net.fabricmc.fabric-api:fabric-api:0.141.4+1.21.11")
    modImplementation(files("libs/deepcrate-1.0.0.jar"))
}

Ce dossier libs/ appartient au projet de l'addon lui-même, à côté de son script de build, et n'existe que pour que le code compile : un joueur installe DeepCrate de façon ordinaire, le jar posé dans mods/ comme n'importe quel mod.

Puis la classe elle-même. onDeepCrateInit() tourne une fois les onze paliers livrés en place, avant que quoi que ce soit ne lise un registre :

SlateCrateAddon.javapackage com.example.slatecrate;

import net.minecraft.core.registries.Registries;
import net.minecraft.resources.Identifier;
import net.minecraft.tags.TagKey;
import net.minecraft.world.item.Item;
import oas.dreyka.deepcrate.api.CrateTier;
import oas.dreyka.deepcrate.api.DeepCrateAddon;
import oas.dreyka.deepcrate.api.DeepCrateApi;
import oas.dreyka.deepcrate.api.module.CrateModule;

public final class SlateCrateAddon implements DeepCrateAddon {
    private static final String NAMESPACE = "slatecrate";

    @Override
    public void onDeepCrateInit() {
        Identifier crate = Identifier.fromNamespaceAndPath(NAMESPACE, "slate_crate");
        DeepCrateApi.registerTier(new CrateTier(crate, 10, SlateCrateBlocks.SLATE_CRATE));

        Identifier module = Identifier.fromNamespaceAndPath(NAMESPACE, "module_1024");
        DeepCrateApi.registerModule(new CrateModule(module, 1024, TagKey.create(Registries.ITEM, module)));
    }
}

Dix rangées de neuf cases, et un module qui monte chaque case à 1024. Le module pointe sur une étiquette d'objet portant son propre nom, donc n'importe quel objet ajouté à slatecrate:module_1024 devient ce module sans une ligne de plus. Ajouter le vôtre à deepcrate:module_512 marche pareil, et ne demande alors aucun Java du tout.

Ce qui reste fermé, et pourquoi

Un palier reste du Java. Il porte un bloc, les blocs entrent dans le registre pendant le chargement des mods, et ce registre est gelé bien avant la lecture du premier fichier de données : un coffre déclaré en JSON arriverait sans rien sur quoi tenir.

L'évènement de mise en page a le dernier mot sur la pagination, mais pas sur le fait de cacher des rangées. Une mise en page dont les pages ne couvrent pas le coffre est refusée, la répartition équilibrée reprend la main, et la raison est écrite dans le journal.

Ce qui mord en premier. L'écran vous tend un CrateScreenArea : le coin du panneau, sa taille, de quoi ajouter un widget, et keepClickable. Déclarez par ce dernier tout rectangle dessiné au-delà du bord du panneau, parce que le jeu compte un clic hors d'un écran de conteneur comme un clic dans le monde, et en relâcher un là jette par terre ce que le joueur tient.

Où signaler ce qui casse

Les tickets du dépôt, github.com/Dreyka-Oas/DeepCrate/issues, la même adresse que le bouton en bas de l'accueil. Un point d'entrée qui a bougé sans être annoncé s'y déclare comme le reste, et les défauts déjà connus y sont ouverts ou fermés à la vue de tous plutôt que dans une boîte de réception.

L'écran d'un coffre de cuivre avec un petit bouton posé par un addon en bas à droite, au-delà du bord du panneau.
Le bouton en bas à droite vient d'un addon, posé par CrateScreenCallback.

La licence, pour qui reprend le code

Le mod est sous licence MIT, pas une licence fermée. Le jouer, le partager, le vendre, le forker et publier un addon construit dessus ne demande aucun accord préalable. Copier un morceau du code dans un autre projet garde avec lui la seule chose que la licence exige : l'avis de copyright et l'avis de permission attachés à cette copie. Elle ne demande rien de plus, ni crédit dans un README, ni obligation d'ouvrir le code de l'addon. Le texte complet se trouve dans le fichier LICENSE du dépôt et dans le champ license de fabric.mod.json, et c'est lui qui fait foi plutôt que cette page. Écrire un addon contre les douze points ci-dessus ne demande aucun accord : c'est ce pour quoi ils existent.