---
title: Codecs
type: docs
weight: 3
---

Les codecs dans Hytale fournissent un moyen puissant de sérialiser et désérialiser des données. Ils sont utilisés pour les fichiers de configuration, la communication réseau et la persistance des données.

**Package:** `com.hypixel.hytale.codec`

## BuilderCodec

Le `BuilderCodec` est le type de codec principal pour les objets complexes. Il utilise un pattern builder pour la construction.

### Définir un Codec

```java
import com.hypixel.hytale.codec.Codec;
import com.hypixel.hytale.codec.KeyedCodec;
import com.hypixel.hytale.codec.builder.BuilderCodec;

public class MyConfig {
    private String serverName;
    private int maxPlayers = 20;  // Valeur par défaut
    private boolean debugMode = false;

    public static final BuilderCodec<MyConfig> CODEC = BuilderCodec.builder(MyConfig.class, MyConfig::new)
        .append(new KeyedCodec<>("ServerName", Codec.STRING),
            (config, val) -> config.serverName = val,
            config -> config.serverName)
        .add()
        .append(new KeyedCodec<>("MaxPlayers", Codec.INTEGER),
            (config, val) -> config.maxPlayers = val,
            config -> config.maxPlayers)
        .add()
        .append(new KeyedCodec<>("DebugMode", Codec.BOOLEAN),
            (config, val) -> config.debugMode = val,
            config -> config.debugMode)
        .add()
        .build();

    // Getters...
    public String getServerName() { return serverName; }
    public int getMaxPlayers() { return maxPlayers; }
    public boolean isDebugMode() { return debugMode; }
}
```

{{< callout type="warning" >}}
**Les clés KeyedCodec doivent commencer par une majuscule** (PascalCase). Les clés comme `"serverName"` lanceront une `IllegalArgumentException`.
{{< /callout >}}

### Structure JSON

Le codec ci-dessus correspond à ce JSON :

```json
{
  "ServerName": "Mon Serveur",
  "MaxPlayers": 100,
  "DebugMode": true
}
```

## Codecs de Base

Hytale fournit des codecs pour les types primitifs :

| Codec | Type |
|-------|------|
| `Codec.STRING` | String |
| `Codec.INTEGER` | Integer |
| `Codec.LONG` | Long |
| `Codec.FLOAT` | Float |
| `Codec.DOUBLE` | Double |
| `Codec.BOOLEAN` | Boolean |
| `Codec.BYTE` | Byte |
| `Codec.SHORT` | Short |

## Utilisation des Fichiers de Config

Enregistrez les fichiers de configuration dans `setup()` :

```java
import com.hypixel.hytale.server.core.util.Config;
import java.util.logging.Level;

private Config<MyConfig> config;

@Override
public void setup() {
    config = withConfig(MyConfig.CODEC);
}

@Override
public void start() {
    MyConfig cfg = config.get();
    getLogger().at(Level.INFO).log("Nom du serveur : " + cfg.getServerName());
}
```

### Emplacement du Fichier Config

Les fichiers de config sont automatiquement stockés dans le répertoire de données de votre plugin :

```
Plugins/
└── your-plugin/
    └── config.json
```

### Configs Nommées

Vous pouvez avoir plusieurs fichiers de configuration :

```java
Config<MyConfig> mainConfig = withConfig("main", MyConfig.CODEC);
Config<DatabaseConfig> dbConfig = withConfig("database", DatabaseConfig.CODEC);
```

## Champs Requis vs Optionnels

Par défaut, tous les champs sont **optionnels**. Pour rendre un champ requis, ajoutez un validateur :

```java
import com.hypixel.hytale.codec.validation.Validators;

BuilderCodec.builder(MyConfig.class, MyConfig::new)
    .append(new KeyedCodec<>("ServerName", Codec.STRING),
        (config, val) -> config.serverName = val,
        config -> config.serverName)
    .addValidator(Validators.nonNull())  // Rend le champ requis
    .add()
    .append(new KeyedCodec<>("MaxPlayers", Codec.INTEGER),
        (config, val) -> config.maxPlayers = val,
        config -> config.maxPlayers)
    .add()  // Optionnel - utilise la valeur par défaut de la classe
    .build();
```

## Codecs List et Map

Pour les collections :

```java
import com.hypixel.hytale.codec.codecs.array.ArrayCodec;
import com.hypixel.hytale.codec.codecs.map.ObjectMapCodec;

// Tableau de strings
Codec<String[]> stringArray = new ArrayCodec<>(Codec.STRING, String[]::new);

// Map avec clés string
Codec<Map<String, Integer>> stringIntMap = new ObjectMapCodec<>(
    Codec.INTEGER,
    LinkedHashMap::new,
    key -> key,           // Clé vers string
    str -> str            // String vers clé
);
```

## Codecs Enum

Pour les types enum :

```java
import com.hypixel.hytale.codec.codecs.EnumCodec;

public enum GameMode {
    SURVIVAL, CREATIVE, ADVENTURE
}

Codec<GameMode> gameModeCodec = new EnumCodec<>(GameMode.class);
```

## Codecs Imbriqués

Les codecs peuvent être imbriqués pour des structures complexes :

```java
public class ServerSettings {
    private GeneralSettings general;
    private DatabaseSettings database;

    public static final BuilderCodec<ServerSettings> CODEC = BuilderCodec.builder(ServerSettings.class, ServerSettings::new)
        .append(new KeyedCodec<>("General", GeneralSettings.CODEC),
            (s, val) -> s.general = val,
            s -> s.general)
        .add()
        .append(new KeyedCodec<>("Database", DatabaseSettings.CODEC),
            (s, val) -> s.database = val,
            s -> s.database)
        .add()
        .build();
}
```

## Héritage

Utilisez des codecs parents pour les hiérarchies de classes :

```java
// Codec classe de base
public static final BuilderCodec<BaseEntity> BASE_CODEC = BuilderCodec.builder(BaseEntity.class, BaseEntity::new)
    .append(new KeyedCodec<>("Id", Codec.STRING),
        (e, val) -> e.id = val,
        e -> e.id)
    .add()
    .build();

// Le codec classe enfant hérite du parent
public static final BuilderCodec<PlayerEntity> CODEC = BuilderCodec.builder(PlayerEntity.class, PlayerEntity::new, BASE_CODEC)
    .append(new KeyedCodec<>("Username", Codec.STRING),
        (e, val) -> e.username = val,
        e -> e.username)
    .add()
    .build();
```

## Bonnes Pratiques

{{< callout type="tip" >}}
- Définissez les codecs comme champs `public static final`
- Utilisez PascalCase pour les clés JSON (ex : `"ServerName"`, pas `"serverName"`)
- Définissez les valeurs par défaut dans les déclarations de champs de classe
- Utilisez `Validators.nonNull()` pour les champs requis
- Gardez les classes de configuration avec des setters simples pour la compatibilité codec
{{< /callout >}}
