Jump to content

[1.14.2] Entity Type Registry


Lycanite

Recommended Posts

I understand Forge for 1.14 is still beta but I've searched around a lot and can't find how far along it is for modded entities so figured I'd ask about this problem I'm having here, if anyone has modded entities going in 1.14.2 perhaps you can show me where I'm going wrong, etc. If it is just a Forge beta thing then that's all good, I know I can just chill for a bit until things are ready.

 

So I register my Entity Types like this: Gitlab Link

	@SubscribeEvent
	public void registerEntities(RegistryEvent.Register<EntityType<?>> event) {
		LycanitesMobs.logDebug("Creature", "Forge registering all " + this.creatures.size() + " creatures...");
		for(CreatureInfo creatureInfo : this.creatures.values()) {
			event.getRegistry().register(creatureInfo.getEntityType());
		}
	}

 

I build them like this: Gitlab Link

	public EntityType getEntityType() {
		if(this.entityType == null) {
			EntityType.Builder entityTypeBuilder = EntityType.Builder.create(EntityFactory.getInstance(), this.peaceful ? EntityClassification.CREATURE : EntityClassification.MONSTER);
			//entityTypeBuilder.setCustomClientFactory(EntityFactory.getInstance().createOnClientFunction); Client Factory never called.
			entityTypeBuilder.setTrackingRange(this.isBoss() ? 32 : 10);
			entityTypeBuilder.setUpdateInterval(3);
			entityTypeBuilder.setShouldReceiveVelocityUpdates(false);
			entityTypeBuilder.size((float)this.width, (float)this.height);
			entityTypeBuilder.disableSerialization();
			this.entityType = entityTypeBuilder.build(this.getName());
			this.entityType.setRegistryName(this.modInfo.modid, this.getName());
			EntityFactory.getInstance().addEntityType(this.entityType, this.entityClass);
		}
		return this.entityType;
	}

 

My factory's create function is this: Gitlab Link

	@Override
	public Entity create(EntityType entityType, World world) {
		LycanitesMobs.logDebug("", "Spawning entity: " + this.entityTypeConstrcutorMap.get(entityType).toString() + " Type: " + entityType.getName() + " Classification: " + entityType.getClassification()); // Name always shows pig!
		Class<? extends Entity> entityConstrcutor = this.entityTypeConstrcutorMap.get(entityType);

		try {
			Entity entity = entityConstrcutor.newInstance(entityType, world);
			world.addEntity(entity);
			return entity;
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		}

		return null;
	}

 

The problem I'm having is that on the client they always spawn as EntityPigs and immediately trigger a crash because the entity Data Manager is casting a Byte to a Bool, I'm assuming this is because on the server side the correct entity has spawned with a different set of Data manager keys:

java.lang.ClassCastException: java.lang.Byte cannot be cast to java.lang.Boolean
	at net.minecraft.entity.AgeableEntity.getGrowingAge(AgeableEntity.java:71) ~[forge-1.14.2-26.0.33_mapped_snapshot_20190618-1.14.2-recomp.jar:?] {}
	at net.minecraft.entity.passive.AnimalEntity.livingTick(AnimalEntity.java:49) ~[forge-1.14.2-26.0.33_mapped_snapshot_20190618-1.14.2-recomp.jar:?] {}
	at net.minecraft.entity.LivingEntity.tick(LivingEntity.java:2178) ~[forge-1.14.2-26.0.33_mapped_snapshot_20190618-1.14.2-recomp.jar:?] {}
	at net.minecraft.entity.MobEntity.tick(MobEntity.java:308) ~[forge-1.14.2-26.0.33_mapped_snapshot_20190618-1.14.2-recomp.jar:?] {pl:accesstransformer:B}
	at net.minecraft.client.world.ClientWorld.func_217418_a(ClientWorld.java:167) ~[forge-1.14.2-26.0.33_mapped_snapshot_20190618-1.14.2-recomp.jar:?] {pl:accesstransformer:B,pl:runtimedistcleaner:A}

 

Looking further into this, on both the client and server, when logging what's being registered, if I call getName or TranslationKey on the EntityType I always get back entity.minecraft.pig. Here's an example that is logged from here (which is called from getEntityType() posed above):

[13:14:06.710] [modloading-worker-9/DEBUG] [co.ly.LycanitesMobs/]: [LycanitesMobs] [Debug] [] Adding entity: class com.lycanitesmobs.core.entity.creature.EntityArisaur Type: TranslatableComponent{key='entity.minecraft.pig', args=[], siblings=[], style=Style{hasParent=false, color=null, bold=null, italic=null, underlined=null, obfuscated=null, clickEvent=null, hoverEvent=null, insertion=null}} Classification: MONSTER

Here the entity class being registered is correct and each EntityType for each entity I'm registering is definitely unique, but they call still translate as a pig.

 

I can also confirm that my Entity Factory is working correctly server side but it is never called client side, I've also tried using the Custom Client Factory, but it is never called by the client as it seems the client is always treating the EntityType as the default vanilla PIG EntityType instance.

 

Also here is an example of one of my DataManager entries:

protected static final DataParameter<Byte> TARGET = EntityDataManager.createKey(EntityCreatureBase.class, DataSerializers.BYTE);

I've made sure that I always provide the correct entity class when creating a key and I'm also assuming that this is the byte sent from the server that the client is trying to cast into a boolean as it is the first DataParameter I register for all entities in my mod.

 

The entire mod is available on Gitlab if anyone wants to look further into things.

Edited by Lycanite
Link to comment
Share on other sites

  • It's currently done via reflection because each entity is defined via a JSON file which provides the class as a string, this is just temporary though, as I later plan on changing this so that I just have one generic entity class instead that is based on the json, but it's going to take a while for me to create AI goals, control behavior, etc all from JSON definitions but it's my end goal there.
  • I've fixed the factory, when first updating from 1.12.2 I thought the factory had to spawn and forgot to remove that, so that is corrected now.
  • For the exception, this is just temporary and will go away once I finish the generic entity class in the future, for now I'm just trying to get entities showing up in the world, I can return a fallback entity instead of null, but getConstructor requires a try catch, what I'll do instead is pre load the constructor instance when the json is being parsed at startup, that should solve performance and eliminates the try catch. Either way, all entity classes involved always have that constructor available so that exception will never show up and shouldn't relate to the problem, but thanks for the feedback.
Link to comment
Share on other sites

52 minutes ago, diesieben07 said:

You never register your entities (or any other registry entries), because you register your event handlers for RegistryEvent.Register in FMLCommonSetupEvent. Registry events fire before FMLCommonSetupEvent, mostly to discourage making registry entries config dependent. You should always register all of your registry entries, regardless of configuration. Do not create registry entries dynamically.

Ah I see, I've moved my event registration into the main mod class' constructor, but the same issue is happening. Before moving them I was still getting log output from my event listeners though.

 

I've also tested with using @Mod.EventBusSubscriber directly on the class that registers entities with the same issue also.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.