mojira.dev
MC-27442

Horse Spawners cannot have SpawnData or SpawnPotentials or they crash

Please, do not close this issue as a duplicate of an Invalid or Duplicate report!

I've seen many people try to report this bug, always to have it closed as a duplicate of MC-16257 or a duplicate of a duplicate of MC-16257. The outcome is the same: a valid ticket is closed as a duplicate of an "invalid" one, hindering chances of this bug ever being fixed. Either re-open MC-16257, or do not close this as a duplicate, please. What follows is some pretty solid evidence that this bug is not Invalid.

What I expected to happen:
Horse spawners would work in the game whether or not SpawnData/SpawnPotentials are present.

What actually happened:
The game crashed in response to a horse spawner if and only if it had SpawnData or SpawnPotentials. This renders it impossible to create a custom horse spawner in vanilla Minecraft.

Why this is not Invalid:
Contrary to Dinnerbone's claim, this crash does not only happen due to invalid entity IDs. A spawner with the EntityID "EntityHorse" will not cause a crash, unless it also includes SpawnData or SpawnPotentials. This behavior is unique to EntityHorse; no other entity causes crashes if and only if a spawner attempts to customize its properties.

Steps to Reproduce:

  1. Import the attached "Good Random Horse" schematic into your world.

  2. Observe that it spawns horses, but they are random. Also observe that no horse is spinning in the spawner cage.

  3. Import the attached "Bad Horse" schematic into your world.

  4. Observe that it, too, does not crash the game...

  5. Wait until it spawns a horse, and observe that your game has crashed! Not consistent or logical behavior at all, is it?

Semi-viable Workaround:

  1. Import the attached "Forced Good Custom Horse" schematic into your world. This schematic makes use of entity riding to hide the horse from the player until it has already been spawned, narrowly avoiding the crash (the developer console still gets spammed with stacktraces however - more on that below).

  2. Observe that it spawns white horses every time.

  3. More importantly, observe that it does not stop spawning horses regardless of how many are nearby. It also allows horses to spawn underwater, in darkness, or even inside solid blocks. The workaround may avoid causing the crash, but I certainly wouldn't call this a permanent solution!

  4. Note that the spawner's odd behavior is actually intended: the rider of the horses is a quickly-despawning XPOrb. Thus, the spawner's entity cap and spawn condition rules follow those of XPOrbs. Please don't change this behavior; many spawner setups make use of the "topmost entity defines spawning conditions" behavior and would break if it were changed (the behavior allows mapmakers to customize spawning conditions to suit their needs). The "Forced Good Custom Horse" schematic doesn't need any fixing - "Bad Horse" does!

The Cause:
I'm not sure why this would happen, but check out "Console Spam InvocationTargetException.txt" - it's an incredibly long stacktrace which occurs prior to the crash. It's not part of the crash report, so I don't think anyone's reported it yet. It's produced by EntityList.createEntityByName (MCP name) when trying to render any horse spawner (any of the three attached schematics): this is why the entity is null by the time the game hits line 110 of the spawner logic class, causing the crash. This is also what differentiates this from your average "unknown entity ID" crash - the ID is not unknown, but I have no idea why the reflection calls fail.

EDIT: I have found the cause; I've posted in-detail below. To sum it up briefly, horses don't accept instantiation with a null world, which happens to be a requirement for mobs to not cause crashes with SpawnData spawners.

Linked issues

MC-16257 Creative world crashed after being opened in new snapshot (13w21a). Resolved MC-16461 Monster Spawner Crash Resolved MC-16609 I had a redstone-toggled spawner in my map to spawn horses in 13w19a and when I went to 13w21a, my game crashed. Resolved MC-16844 Approaching a skeleton horse spawner crashes the game (Zombie horse hasn't been tested) Resolved MC-19177 Crash upon loading world Resolved

Attachments

Comments 25

Can confirm this bug for MC 1.6.2. It is very unfortunate, too. It is impossible to spawn a horse with a saddle or armor. Additionally you cannot spawn a horse with specific attributes, which would benefit custom maps greatly. (same speed, no jump/very high jump, etc.)

http://imgur.com/a/DrCFf

In the 1.6 snapshots this didn't crash the game.

Even if you spawn a horse riding a snowball the game crashes.

Examining the console spam made me realize something interesting: the game fails to createEntityByName on horse altogether - that spam is so large because the game's continuously trying to create a horse for the spawner and failing to do so. This is why horse spawners have an empty cage even if they don't have SpawnData and don't cause crashes!

The cause, unsurprisingly, is within the EntityHorse class itself:

Client> Caused by: java.lang.NullPointerException
Client> 	at rr.cI(SourceFile:448)
Client> 	at rr.cH(SourceFile:444)
Client> 	at rr.<init>(SourceFile:140)
Client> 	... 17 more

The problem isn't that the game doesn't know what to spawn - it's that DrZhark's horses can't be instantiated this way. The InvocationTargetException means that the constructor itself throws an exception. A Minecraft Coder Pack snippet of the immediate cause of this failure:

private void func_110232_cE()
    {
        if (!this.worldObj.isRemote)
        {
            this.func_110251_o(this.field_110296_bG.getStackInSlot(0) != null);

            if (this.func_110259_cr())
            {
                this.func_110236_r(this.func_110260_d(this.field_110296_bG.getStackInSlot(1)));
            }
        }
    }

Apparently, worldObj is null when this line is called - and what a surprise!

public Entity func_98281_h()
    {
        if (this.field_98291_j == null)
        {
            Entity var1 = EntityList.createEntityByName(this.getEntityNameToSpawn(), (World)null);
            var1 = this.func_98265_a(var1);
            this.field_98291_j = var1;
        }

        return this.field_98291_j;
    }

The base cause of this issue is that horses are the only mob which cannot be created in a null world! The spawner attempts to construct an entity for the spawnercage, and a null world is provided because this entity is not intended to be "real". It fails because Horses don't follow the null-world-is-okay standard that other mobs follow, and thus the spawnercage entity is null. This, in turn, causes a crash if SpawnData is present, because the game then makes the assumption that the spawnercage entity is not null.

Thus, you get a crash identical to those seen by people who try creating spawners with invalid EntityIDs, despite the cause being very, very different.

I noticed something in the code: if Riding is present, the game will attempt to create a fake entity for the ridden entity as well, but if it fails, it gracefully continues instead of crashing. This means it is possible to trick the game into spawning custom horses, but the developer console is still spammed with InvocationTargetExceptions.

This is a good workaround for the time being, but there's one troubling consequence: such a spawner follows the entity cap of the rider (a very useful trick 99% of the time, I might add, so please don't change this behavior!). This means that, if you use/abuse this trick to get your horse spawners to work, they will not stop spawning regardless of how many horses you have. This'll be a bit of a problem for a horse stable I was working on, but I suppose it's better than nothing.

This renders it impossible to create a custom horse spawner in vanilla Minecraft.

Working as intended.

Mateus Salviano

I did the tests myself, I really can't spawn a vanilla horse with spawners, the world just crashes.
Yet Grum confirms "Working as intended", is the crash really intentional? If yes, may I ask why?

15 more comments

The ticket you're posting on only applies to horse spawners. That's why this is closed; Grum's statement only applies to horse spawners with SpawnData/SpawnPotentials. You're making a Witch spawner.

For your spawner, you made the first equipment array the wrong length. Correct it to this, and no crash occurs:

setblock ~ ~1 ~ minecraft:mob_spawner 0 replace {EntityId:Witch,SpawnData:{Equipment:[{},{},{},{},
{id:276,Count:1}
]},SpawnPotentials:[{Type:Witch,Weight:1,Properties:{Equipment:[{},{},{},{},
{id:46,Count:1}
]}}]}

Also, witches use their weapon slot to store potions they drink. Don't be surprised if that item doesn't appear at all - Dinnerbone said it's just beyond what's currently possible with witch NBT.

EDIT: actually, I can't get it to crash even if I use the same tags you used.

Warren Liddell

i've used the same tag's many times before an simply changed the monster and its hasnt crashed, but for some reason this time it did and it's a permanent crash with that map chunk, i was hoping the crash report would enlighten to what/why it was occuring. The witches and/or zombies when spawned are holding the diamond sword np's, but i didnt expect them to drop the sword but only the normal drop's they have.. This is why its perplexing as ive been using that style tag with no side effects untill now.

@Kumasasa if you read this,

MC-43567 is NOT a dupe of this.

This is related to invalid parameters,MC-43567 is related to bad characters!

@Professor Epic Anonomus: Changed the resolution of MC-43567

Seems to be fixed in 1.8.5, 1.8.6 (and maybe earlier)

Command

/setblock ~ ~1 ~ mob_spawner 0 replace {Delay:702s,EntityId:"EntityHorse",MaxNearbyEntities:6s,MaxSpawnDelay:800s,MinSpawnDelay:200s,RequiredPlayerRange:16s,SpawnCount:4s,SpawnPotentials:[{Properties:{},Type:"EntityHorse",Weight:1}],SpawnRange:4s}

WolfieMario

(Unassigned)

Community Consensus

crash, horse, spawner

Minecraft 1.6.2

Retrieved