ModelComponent
Visual model reference for entities. Wraps a Model instance that defines appearance, animations, bounding box, and physics.
Access
Section titled “Access”ModelComponent modelComponent = store.getComponent(ref, ModelComponent.getComponentType());Model model = modelComponent.getModel();Model Properties
Section titled “Model Properties”Model model = modelComponent.getModel();
// identityString assetId = model.getModelAssetId(); // e.g. "Player", "Zombie"
// scalefloat scale = model.getScale();
// visual pathsString modelPath = model.getModel(); // .blockymodel fileString texturePath = model.getTexture();
// dimensionsBox boundingBox = model.getBoundingBox();float eyeHeight = model.getEyeHeight();
// physics (used if no PhysicsValues component)PhysicsValues physics = model.getPhysicsValues();
// attachments (equipment slots, etc.)ModelAttachment[] attachments = model.getAttachments();Map<String, String> attachmentIds = model.getRandomAttachmentIds();Creating Models
Section titled “Creating Models”Models are created from ModelAsset definitions:
// get asset from registryModelAsset asset = ModelAsset.getAssetMap().getAsset("Zombie");
// create model with specific scaleModel model = Model.createScaledModel(asset, 1.5f);
// create with unit scale (1.0)Model model = Model.createUnitScaleModel(asset);
// create with random scale (within asset's min/max)Model model = Model.createRandomScaleModel(asset);
// create with attachmentsMap<String, String> attachments = new HashMap<>();attachments.put("head", "knight_helmet");attachments.put("hand_right", "iron_sword");Model model = Model.createScaledModel(asset, 1.0f, attachments);Changing an Entity’s Model
Section titled “Changing an Entity’s Model”// create new modelModelAsset asset = ModelAsset.getAssetMap().getAsset("Skeleton");Model newModel = Model.createScaledModel(asset, 1.0f);
// replace componentstore.putComponent(ref, ModelComponent.getComponentType(), new ModelComponent(newModel));When the model changes, ModelSystems.UpdateBoundingBox automatically updates the entity’s BoundingBox component.
Changing Attachments
Section titled “Changing Attachments”To change equipment/attachments on an existing model:
ModelComponent modelComponent = store.getComponent(ref, ModelComponent.getComponentType());Model currentModel = modelComponent.getModel();
// get the assetModelAsset asset = ModelAsset.getAssetMap().getAsset(currentModel.getModelAssetId());
// copy current attachments and modifyMap<String, String> attachments = new HashMap<>(currentModel.getRandomAttachmentIds());attachments.put("head", "crown");
// create new model with updated attachmentsModel newModel = Model.createScaledModel(asset, currentModel.getScale(), attachments);store.putComponent(ref, ModelComponent.getComponentType(), new ModelComponent(newModel));Crouching
Section titled “Crouching”Models can have different bounding boxes for crouching:
Box normalBox = model.getBoundingBox();Box crouchBox = model.getCrouchBoundingBox();float crouchOffset = model.getCrouchOffset();
// or get box based on movement stateBox currentBox = model.getBoundingBox(movementStates);Animations
Section titled “Animations”Check if animations exist before playing:
Model model = modelComponent.getModel();Map<String, ModelAsset.AnimationSet> animations = model.getAnimationSetMap();
// get animation with fallbackString animId = model.getFirstBoundAnimationId("attack_swing", "attack");See animation system documentation for playing animations.
PersistentModel
Section titled “PersistentModel”For models that should persist across save/load, use PersistentModel:
// save model referenceModel.ModelReference modelRef = model.toReference();store.putComponent(entityRef, PersistentModel.getComponentType(), new PersistentModel(modelRef));
// restore model from referencePersistentModel persistent = store.getComponent(entityRef, PersistentModel.getComponentType());Model restoredModel = persistent.getModelReference().toModel();Network Sync
Section titled “Network Sync”Model changes are tracked via consumeNetworkOutdated() and synced to clients automatically. The component flags itself as outdated when created, ensuring initial sync.