mojira.dev
MC-153319

Result of UUID selector is nondeterministic

The bug

When entities with the same UUID exists in multiple levels, the result of UUID selector (e.g. 0-0-0-0-0) is not guaranteed.

How to reproduce

  1. Add armor stands with the same UUID 0-0-0-0-256e7 in all the levels

    execute in minecraft:the_nether run forceload add 0 0
    execute in minecraft:the_nether run summon minecraft:armor_stand 0 0 0 {UUID: [I; 0, 0, 0, 153319], Marker: true}
    
    execute in minecraft:overworld run forceload add 0 0
    execute in minecraft:overworld run summon minecraft:armor_stand 0 0 0 {UUID: [I; 0, 0, 0, 153319], Marker: true}
    
    execute in minecraft:the_end run forceload add 0 0
    execute in minecraft:the_end run summon minecraft:armor_stand 0 0 0 {UUID: [I; 0, 0, 0, 153319], Marker: true}
data get entity 0-0-0-0-256e7 Dimension

→ ❌ The result is one of the following values: -1, 0, 1. It is nondeterministic and may change each time the game is started.
Furthermore, since the Java API specification of IdentityHashMap does not make guarantees about the order, the result may be completely unpredictable depending on the environment.

Code analysis

IdentityHashMap is used for the levels.
This class makes no guarantees as to the order of the map; in particular, it does not guarantee that the order will remain constant over time.

// net.minecraft.server.MinecraftServer
private final Map<DimensionType, ServerLevel> levels = Maps.newIdentityHashMap();

public Iterable<ServerLevel> getAllLevels() {
    return levels.values();
}

An entity with the specified UUID is searched by iterating the levels that their order is not guaranteed. This causes nondeterminism of UUID selectors.

// net.minecraft.commands.arguments.selector.EntitySelector
public List<? extends Entity> findEntities(CommandSourceStack source) throws CommandSyntaxException {
    ...
    if (entityUUID != null) {
        for (ServerLevel level : source.getServer().getAllLevels()) {
            Entity entity = level.getEntity(entityUUID);
            if (entity == null) continue;
            return Lists.newArrayList(entity);
        }
        return Collections.emptyList();
    }
    ...
}

 

Linked issues

Comments

intsuc

Fixed in 20w21a.
levels is now LinkedHashMap and has deterministic order. That is, UUID selectors always search an entity with the specified UUID from the level with the highest priority and are no longer non-deterministic.

intsuc

(Unassigned)

Confirmed

Commands

UUID

Minecraft 1.14.2, Minecraft 1.14.3 Pre-Release 1, Minecraft 1.14.3 Pre-Release 2, Minecraft 1.14.3 Pre-Release 3, Minecraft 1.14.3 Pre-Release 4, ..., 20w14a, 20w16a, 20w17a, 20w18a, 20w20b

20w21a

Retrieved