Overview
A Tracker is the runtime controller for a specific model instance. It manages the lifecycle, rendering, animation playback, and player interaction for a single spawned model.Think of
ModelRenderer as the blueprint and Tracker as the living instance created from that blueprint.Tracker Types
BetterModel provides two tracker types:EntityTracker
Attached to entities, follows their movement
DummyTracker
Standalone at fixed locations
EntityTracker
EntityTracker attaches to a Minecraft entity and automatically follows its position and rotation.src/main/java/com/example/EntityTrackerExample.java
- Automatically follows entity position and rotation
- Registered in
EntityTrackerRegistryfor the entity - Persists across server restarts (for
GENERALtype models) - Can be retrieved with
getOrCreate()pattern
DummyTracker
DummyTracker spawns a model at a fixed location without an attached entity.src/main/java/com/example/DummyTrackerExample.java
- Stationary position (unless manually updated)
- No entity attachment
- Useful for decorations, holograms, NPCs
- Must be manually closed when no longer needed
Lifecycle Management
Creation
Trackers are created throughModelRenderer:
Scheduling and Ticking
Trackers automatically start a scheduled update task when players are nearby:- Tick Interval: 25ms (40 ticks per second)
- Auto-start: When first player comes in range
- Auto-pause: When no players are in range
- Frame counter: Tracks elapsed ticks since start
The tracker tick rate (
TRACKER_TICK_INTERVAL = 25ms) is faster than Minecraft’s tick rate (50ms) to provide smooth animations.Pausing and Resuming
Closing
Always close trackers when they’re no longer needed:CloseReason
Manually removed via
close() - tracker state is not savedCloseReason
Plugin is disabling - tracker state is saved for
GENERAL modelsCloseReason
Entity despawned - tracker state is saved for
GENERAL modelsPlayer Visibility
Spawning for Players
Trackers automatically spawn display entities for players in range:Hiding and Showing
Removing from Players
Despawning
Scheduled Tasks
Frame Handlers
Execute code every tracker tick (25ms):Tick Handlers
Execute code every Minecraft tick (50ms):Scheduled Tasks
Schedule tasks at custom intervals:Main Thread Tasks
Schedule tasks to run on the main thread:Per-Player Tasks
Run code for each visible player every tick:Rotation and Scaling
Rotation
Control how the model rotates:Rotation Strategies
Scaling
Accessing Bones
Get individual bones for manipulation:Display Entities
Access underlying display entities:Model Height
Get the calculated height of the model:Height is calculated from head-tagged bones and cached per tick for performance.
Force Updates
Force display entity data updates:EntityTrackerRegistry
For entity-based trackers, access the registry:Best Practices
Always close trackers
Always close trackers
Trackers consume resources. Always close them when no longer needed.
Use getOrCreate for entity trackers
Use getOrCreate for entity trackers
Avoid creating duplicate trackers on the same entity.
Schedule heavy operations
Schedule heavy operations
Don’t run expensive operations in frame handlers. Use tick handlers or scheduled tasks.
Use task() for entity operations
Use task() for entity operations
Entity manipulation must happen on the main thread.
Check isClosed before operations
Check isClosed before operations
Always verify tracker state before operations.
Complete Example
src/main/java/com/example/CompleteTrackerExample.java
See Also
Models & Renderers
Creating trackers from models
Animations
Playing animations on trackers
Bones & Hitboxes
Manipulating individual bones
API Reference
Complete Tracker API
