5 min

Models & Disguises

Change entity appearances by swapping their model component. Perfect for disguises, transformations, and visual effects.

How Models Work

Every entity has a ModelComponent that determines its appearance. To change how an entity looks, you replace this component with a new one pointing to a different model asset.

thread safety
Model changes modify components, so they MUST run inside world.execute().

Changing Models

Basic Model Change

1private void disguiseAsCreature(Player player, String modelName) {
2 World world = player.getWorld();
3
4 world.execute(() -> {
5 // Get the model asset
6 DefaultAssetMap<String, ModelAsset> assetMap = ModelAsset.getAssetMap();
7 ModelAsset asset = assetMap.getAsset(modelName);
8
9 if (asset == null) {
10 getLogger().warn("Model not found: " + modelName);
11 return;
12 }
13
14 // Create model with default scale
15 Model model = Model.createUnitScaleModel(asset);
16
17 // Create component and apply
18 ModelComponent component = new ModelComponent(model);
19
20 Ref ref = player.getReference();
21 Store store = ref.getStore();
22 store.putComponent(ref, ModelComponent.getComponentType(), component);
23 });
24}

Model with Custom Scale

1private void setModelWithScale(Player player, String modelName, float scale) {
2 player.getWorld().execute(() -> {
3 ModelAsset asset = ModelAsset.getAssetMap().getAsset(modelName);
4
5 // Create model with custom scale
6 Model model = Model.createModel(asset, scale);
7
8 ModelComponent component = new ModelComponent(model);
9 applyComponent(player, component);
10 });
11}

Common Model Names

modeldescription
MouseSmall rodent creature
TrorkHostile goblin-like mob
KweebecFriendly forest creature
ChickenFarm animal
PigFarm animal
GhostTransparent spectral entity
SkeletonBone creature
discovering models
Model names correspond to asset files in the game data. Explore the server JAR or game files to find available models.

Reset to Default

Restore a player's original model:

1private void resetPlayerModel(Player player) {
2 player.getWorld().execute(() -> {
3 // Get the default player model
4 ModelAsset playerAsset = ModelAsset.getAssetMap().getAsset("Player");
5 Model model = Model.createUnitScaleModel(playerAsset);
6
7 ModelComponent component = new ModelComponent(model);
8 applyComponent(player, component);
9 });
10}
11
12// Usage
13resetPlayerModel(player);

Disguise System Example

DisguiseManager.javajava
1public class DisguiseManager {
2
3 private final MapString> originalModels = new HashMap<>();
4
5 public void disguise(Player player, String modelName) {
6 World world = player.getWorld();
7
8 world.execute(() -> {
9 // Store original model if not already disguised
10 if (!originalModels.containsKey(player.getUuid())) {
11 String current = getCurrentModel(player);
12 originalModels.put(player.getUuid(), current);
13 }
14
15 // Apply new model
16 setModel(player, modelName);
17 });
18 }
19
20 public void undisguise(Player player) {
21 World world = player.getWorld();
22
23 world.execute(() -> {
24 String original = originalModels.remove(player.getUuid());
25 if (original != null) {
26 setModel(player, original);
27 }
28 });
29 }
30
31 public boolean isDisguised(Player player) {
32 return originalModels.containsKey(player.getUuid());
33 }
34
35 private void setModel(Player player, String modelName) {
36 ModelAsset asset = ModelAsset.getAssetMap().getAsset(modelName);
37 Model model = Model.createUnitScaleModel(asset);
38 ModelComponent component = new ModelComponent(model);
39
40 Ref ref = player.getReference();
41 ref.getStore().putComponent(ref, ModelComponent.getComponentType(), component);
42 }
43
44 private String getCurrentModel(Player player) {
45 Ref ref = player.getReference();
46 ModelComponent comp = ref.getStore().getComponent(
47 ref,
48 ModelComponent.getComponentType()
49 );
50 return comp != null ? comp.getModel().getAsset().getName() : "Player";
51 }
52}

Command Integration

1// Disguise command
2getEventRegistry().register(PlayerChatEvent.class, event -> {
3 String msg = event.getMessage();
4 Player player = event.getPlayer();
5
6 if (msg.startsWith("/disguise ")) {
7 event.setCancelled(true);
8 String modelName = msg.substring(10).trim();
9
10 disguiseManager.disguise(player, modelName);
11 player.sendMessage("Disguised as " + modelName);
12 }
13
14 if (msg.equals("/undisguise")) {
15 event.setCancelled(true);
16
17 if (disguiseManager.isDisguised(player)) {
18 disguiseManager.undisguise(player);
19 player.sendMessage("Disguise removed");
20 } else {
21 player.sendMessage("You are not disguised");
22 }
23 }
24});

Best Practices

do
Cache ModelAsset references if using the same model frequently.
do
Handle null assets gracefully - models may not exist on all server versions.
avoid
Don't change models in tight loops - batch model changes when possible.