Synchroniser facilement des données pour vos entitées



  • Sommaire du tutoriel

    Pré-requis

    Introduction

    Lorsque l'on crée une entité un peu complexe, il arrive souvent d'avoirs besoin qu'une donnée reste synchroniser entre le serveur et les clients, la première idée que la plupart des nouveaux moddeurs de forge ont, c'est d'envoyer des paquets lorsque cette dite donnée est changée, cependant minecraft vanilla possédé déjà un système tout fait et prêt d'utilisation qui permettra de faciliter votre travail sans avoir besoin de créer de paquet.

    Note

    Le nécessiter d'avoirs une donnée synchronisée avec le client n'est pas limité à une utilisation de rendu uniquement, même s'il s'agit souvent de sa principale utilisation

    Code

    Data Manager

    Chaque entité a un EntityDataManager (ou Data Watcher pour les versions antérieures à la 1.9) stockant des données qu'il synchronise lorsqu'une d'entre elles subit une modification. Cela permet de vous éviter de passer par des paquets.

    Attention

    Le Data Manager ne peut supporter que 31 données différentes. Si vous en voulais plus, il faudrait passer par des paquets.

    Data Parameter

    La class DataParameter et une class pouvant contenir une donnée utilisable par la Data Manager, c'est-à-dire une donnée qui peut-être sérialisez via un Data Serializer, minecraft offre 14 différentes données supportées par défaut mais rien ne vous empêche de rajouter votre propre support de n'importe qu'elle type de données.

    Crée votre paramètre

    Pour créer un Data Parameter il faut d'abord créé le paramètre en lui-même en utilisant la méthode EntityDataManager#createKey

    	private static final DataParameter<Type> parameter = EntityDataManager.<Type>createKey(MyEntity.class, DataSerializer);
    
    • Type : Le type est égal au type de données que vous voulez utiliser

    En arguments pour la méthode, il faut la class de votre entity ainsi qu'un DataSerializer supportant le type de donnée utilise.
    Par exemple si je veux synchroniser un Integer, cela donne

    	private static final DataParameter<Integer> my_int_paramater = EntityDataManager.<Integer>createKey(MyEntity.class, DataSerializers.VARINT);
    

    Note

    Liste de tous les types de données supporter par défault par Minecraft

    Type de données supportée DataSerializers
    Byte DataSerializers.BYTE
    Integer DataSerializers .VARINT
    Float DataSerializers.FLOAT
    String DataSerializers.STRING
    ITextComponent DataSerializers.TEXT_COMPONENT
    ItemStack DataSerializers.ITEM_STACK
    Boolean DataSerializers.BOLEAN
    Rotations DataSerializers.ROTATIONS
    BlockPos DataSerializers.BLOCK_POS
    Optional<BlockPos> DataSerializers.OPTIONAL_BLOCK_POS
    EnumFacing DataSerializers.FACING
    Optional<UUID> DataSerializers.OPTIONAL_UNIQUE_ID
    Optional<IBlockState> DataSerializers.OPTIONAL_BLOCK_STATE
    NBTTagCompound DataSerializers.COMPOUND_TAG

    Enregistrer votre paramètre et l'utilisée

    Après avoir créé votre paramètre, il faut l'enregistrer dans votre entité, pour ça on appellera la méthode EntityDataManager#register() dans la méthode entityInit() de votre entity en passant votre paramètre et sa valeur par défaut en tant qu'arguments

    @Override
    protected void entityInit() {
    	super.entityInit();
    	this.dataManager.register(my_int_paramater, 0);
    }
    

    Version 1.9 et antérieur

    @Override
    protected void entityInit() {
    	super.entityInit();
    	this.dataManager.addObject(my_int_paramater, 0);
    }
    

    Attention

    Il faut garder le super.entityInit() car il enregistre lui-même ses propres paramètres. Si vous le gardez pas, votre entité ne fonctionnera pas. Il utilise lui-même un certain nombre de paramètres qui réduit le nombre maximum de paramètre à votre disposition

    Vous voilà avec votre paramètre enregistré, pour modifier sa valeur, il suffit d’appeler les méthodes EntityDataManager#set() pour modifier sa valeur et EntityDataManager#get() pour la lire.

    Note

    Un tableau utile pour savoir les méthodes en fonction des versions

    Les méthodes Pre 1.9 Post 1.9
    Enregister un paramètre DataWatcher#addObject() EntityDataManager#register()
    Changez la valeur d'un paramètre DataWatcher#updateObject() EntityDataManager#set()
    Obtenir la valeur d'un paramètre DataWatcher#getWatchableObject() EntityDataManager#get()

    Maintenant que le jeu sait que votre paramètre existe, il synchronisera votre donnée lorsque vous utiliseriez la méthode EntityDataManager#set() en utilisant les méthodes Entity#writeEntityToNBT() et Entity#readEntityFromNBT(), vous devez donc les @Override et utilisez le nbt pour la synchronisation

    Résultat

    Avec un exemple concret, cela donne donc ceci

    /**
     * @author Wind_Blade
     */
    
    public class MyEntity extends EntityLiving {
    
    	private static final DataParameter<Integer> size = EntityDataManager.<Integer>createKey(MyEntity.class, DataSerializers.VARINT);
    
    	public MyEntity (World worldIn) {
    		super(worldIn);
    	}
    
    	@Override
    	protected void entityInit() {
    		super.entityInit();
    		this.dataManager.register(size, 0);
    	}
    
    	@Override
    	public IEntityLivingData onInitialSpawn(DifficultyInstance difficulty, IEntityLivingData livingdata) {
    		this.setSize(this.rand.nextInt(9));
    		return super.onInitialSpawn(difficulty, livingdata);
    	}
    
    	public int getSize() {
    		return this.dataManager.get(size);
    	}
    
    	public void setSize(int newSize) {
    		this.dataManager.set(size, newSize);
    	}
    
    	@Override
    	public void writeEntityToNBT(NBTTagCompound compound) {
    		super.writeEntityToNBT(compound);
    		compound.setInteger("size", this.dataManager.get(size));
    	}
    
    	@Override
    	public void readEntityFromNBT(NBTTagCompound compound) {
    		super.readEntityFromNBT(compound);
    		this.dataManager.set(sizze, compound.getInteger("size"));
    	}   
    }
    

    Licence et attribution

    Creative Commons

    Ce tutoriel rédigé par @Wind_Blade corrigé par @Wind_Blade et publié sur Minecraft Forge France est mis à disposition selon les termes de la licence Creative Commons Attribution - Pas d’Utilisation Commerciale - Partage dans les Mêmes Conditions 4.0 International

    retour Sommaire des tutoriels