perf: generate user limb skins per limb instead of whole skins
View 5 more changes
User limbs used to cost 10 MineSkin uploads per skin per variant, even for limbs no loaded model used. Limbs are now uploaded on demand, and eager generation on join only covers the limb types that loaded blueprints reference.
- No limb[type=] bone loaded: 0 uploads per joining skin, was 10.
- Default skins: 0 uploads at startup, was 20. They fill in on first use.
- Head, body, arms and legs model: 5 uploads, was 10.
- A failed limb no longer discards the ones that succeeded, so a retry only re-sends what failed.
Premium
R4.1.1
ModelEngine-R4.1.1.jar
Build 2411·
fix: dedupe concurrent user limb generation and avoid caching partial MineSkin failures
Premium
R4.1.1
ModelEngine-R4.1.1.jar
Build 2410·
fix: track=false on pv=true
View 1 more changes
note from tai: i've spent 5+ hours on finding this, send help
Premium
R4.1.1
ModelEngine-R4.1.1.jar
Build 2409·
feat: sub-tick bone transform sampling
View 33 more changes
Opt in per bone, then read by index, where `0` is the previous tick and `n` is the current one.
```java
bone.setSubTickSamples(10); // ancestors are raised to match
Transform t = bone.getSubTickTransform(k); // model space, like getGlobalTransform()
Matrix4f m = bone.getSubTickMatrix(k); // like getTransformMatrix()
Location loc = bone.getSubTickLocation(k);
Location eye = bone.getSubTickLocation(k, OffsetMode.LOCAL, new Vector3f(0, 0.2f, 0), true);
```
Samples go through the animation's own interpolators, so curved segments and step keyframes resolve exactly as they do at tick resolution. `isSubTickStep(k)` marks where a step keyframe landed.
Everything returns `null` (`false` for the step flag) when sampling is off, the index is out of range, or the buffer has not been filled yet, so callers fall back to `getGlobalTransform()`.
## API
| Method | Returns |
| --- | --- |
| `setSubTickSamples(int)` / `getSubTickSamples()` | opt in, `0` disables |
| `getSubTickTransform(int)` | `Transform`, model space |
Bones the animation does not fully drive (bone behaviors, manual animators, procedural transforms) are detected each tick by composing the animation alone and comparing it against what the tick produced. Those interpolate their own two tick transforms instead, which still lands exactly on the tick values at both ends.
Off by default at one null check per bone per tick. When on, `n + 1` animation evaluations and decomposes per opted-in bone per tick.
Supporting changes:
- `SubTickProperty`, a time-shifted read-only view of an `IAnimationProperty`
- `AnimationHandler.updateBone(bone, propertyMapper)`, whose default ignores the mapper so third-party handlers degrade to tick resolution instead of breaking
- `Transform.set`
Premium
R4.1.1
ModelEngine-R4.1.1.jar
Build 2408·
perf: block culling does far less work per player
View 3 more changes
- Block culling used to build the full list of a model's box corners before testing any of them. It now walks the visible faces directly and stops at the first corner that is in view. Same culling decisions, a small fraction of the memory churn, so the cull thread and the GC both get lighter.
- Bone item updates got the same treatment on a smaller scale.
- Fixes models more than 16.7 million blocks from spawn being culled while still visible. The old corner math lost precision that far out and ended up skipping half its checks.
Premium
R4.1.1
ModelEngine-R4.1.1.jar
Build 2407·
perf: nuked main thread usage by 60%
Premium
R4.1.1
ModelEngine-R4.1.1.jar
Build 2406·
fix: i do not like it but it's needed
Premium
R4.1.1
ModelEngine-R4.1.1.jar
Build 2405·
fix: model max health froze after a plugin re-registered the attribute
Premium
R4.1.1
ModelEngine-R4.1.1.jar
Build 2404·
perf: skip the tracking sweep when no viewer left
Premium
R4.1.1
ModelEngine-R4.1.1.jar
Build 2403·
perf: skip repeated work in bone item and behaviour lookups
View 3 more changes
- Updating a bone's items copied a set that was already deduplicated, just to compare it against a set it could never match.
- On Java 21 and newer the copy is now skipped, making the update 14-48% faster when models spawn or change parts.
- Servers on Java 17 (1.19.4 to 1.20.4) keep the copy, since dropping it there would reorder a bone's sub-models.
Premium
R4.1.1
ModelEngine-R4.1.1.jar
Build 2402·
perf: reduce per-entity overhead on the model tick
View 2 more changes
Every model does a few lookups per entity each tick to reach the entity behind it.
These took slower paths than they needed to, and one of them created a throwaway object on every call.
Premium
R4.1.1
ModelEngine-R4.1.1.jar
Build 2401·
fix: seat pivot spawned 0.375 lower than its teleport position
Premium
R4.1.1
ModelEngine-R4.1.1.jar
Build 2400·
api: add UserLimb#getLimbType and UserLimb#setStaticSkin to allow bypassing...
Premium
R4.1.1
ModelEngine-R4.1.1.jar
Build 2399·
feat: camera pivot for first-person billboard models
Premium
R4.1.1
ModelEngine-R4.1.1.jar
Build 2398·
perf: send fewer bytes when a model comes into view
View 3 more changes
Trims redundant clientbound data from the spawn and tracking paths, cutting the traffic burst when a model enters view by roughly 10 to 30 percent.
Savings scale with start-tracking events rather than with viewers standing still.
Also fixes two client disconnects, one under Bundle-Everything and one on the held-item path.
Premium
R4.1.1
ModelEngine-R4.1.1.jar
Build 2397·
chore: version bump to 4.1.1
Premium
R4.1.0
ModelEngine-R4.1.0.jar
Build 2396·
fix: read nametag customName off-thread-safe on Folia
Premium
R4.1.0
ModelEngine-R4.1.0.jar
Build 2395·
fix: support state mechanic srcmodelid on the priority animation handler (#353)
Premium
R4.1.0
ModelEngine-R4.1.0.jar
Build 2394·
fix: migrate CasterModelRotationPlaceholder off deprecated Mythic MetaPlaceholder + mm 5.13
Premium
R4.1.0
ModelEngine-R4.1.0.jar
Build 2393·
fix: add inheritfaction option to bindHitbox
View 4 more changes
bindHitbox always copied the caster's faction onto the bound mob, silently overriding the faction set in the bound mob's own config.
This broke any faction-based targeting of bound mobs, e.g. keeping them alive with remove @children{targetconditions=[ - faction{f=x} false]}.
Set inheritfaction=false (alias: if) on the mechanic to make the bound mob keep its own faction.
Defaults to true, matching summon's inheritfaction, so existing setups are unchanged.
Premium
R4.1.0
ModelEngine-R4.1.0.jar
Build 2314·
Brightness mech now affect nametag bones
Premium
R4.1.0
ModelEngine-R4.1.0.jar
Build 2313·
Initial 26.1 & 26.1.1 support
View 4 more changes
Known bugged feature:
- Core share player model works, but causes some items in inventory to not render. Mineskin player model still works though.
- If your model has elements that has out of bound UV (i.e. UV starts under 0 or ends above the texture size,) the model will render as error cube. Since it is a modeling error, a warning message would be implemented later
26.1+ requires Java 25. If there are any issues please tell Taiyou (cuz I will be gone for the week)
Premium
R4.1.0
ModelEngine-R4.1.0.jar
Build 2312·
Fixed dummy sync location not syncing to body controller
Premium
R4.1.0
ModelEngine-R4.1.0.jar
Build 2311·
clear force pair and hide api
Premium
R4.1.0
ModelEngine-R4.1.0.jar
Build 2310·
Fixed ref animation not removable in state machines
Premium
R4.1.0
ModelEngine-R4.1.0.jar
Build 2309·
Fixed projectile/aura taking priority over targeted entity when finding modeled entity
Premium
R4.1.0
ModelEngine-R4.1.0.jar
Build 2308·
fix: read the bytes instead
Premium
R4.1.0
ModelEngine-R4.1.0.jar
Build 2307·
perf: cache parsed bbmodels and improve I/O buffering
View 1 more changes
Cache BlockbenchModel between reloads using metadata+CRC32. Increase zip/read buffers from 1KB to 64KB. Import: 3.4s → 315ms, Zipping: 1.1s → 510ms.
Premium
R4.1.0
ModelEngine-R4.1.0.jar
Build 2306·
perf: make pack generate faster
Premium
R4.1.0
ModelEngine-R4.1.0.jar
Build 2305·
feat: meg client mod support
Premium
R4.1.0
ModelEngine-R4.1.0.jar
Build 2304·
perf: reduce redundant metadata on spawn and cull transition
Premium
R4.1.0
ModelEngine-R4.1.0.jar
Build 2303·
fix: guard interpolation delay with per-player snapshot check
View 1 more changes
Move snapshot computation before the interpolation delay condition so DISPLAY_INTERPOLATION_DELAY is only sent when the player actually has stale transform data. Previously, the delay was added based on the bone-level dirty flag alone, before the per-player snapshot was even computed. Also adds missing empty entity data guard to v1_20_R4.
Premium
R4.1.0
ModelEngine-R4.1.0.jar
Build 2302·
fix: use UUID keys in SelectionManager to prevent watchdog hang
Premium
R4.1.0
ModelEngine-R4.1.0.jar
Build 2301·
fix: reduce redundant metadata on cull transition
Premium
R4.1.0
ModelEngine-R4.1.0.jar
Build 2300·
fix: Mount related desync issues
Premium
R4.1.0
ModelEngine-R4.1.0.jar
Build 2299·
fix: OBB related issues
Premium
R4.1.0
ModelEngine-R4.1.0.jar
Build 2298·
fix: re-do the folia bullshits
Premium
R4.1.0
ModelEngine-R4.1.0.jar
Build 2297·
fix: Folia thread safety for mount system
Premium
R4.1.0
ModelEngine-R4.1.0.jar
Build 2296·
fix: aura MEG attachment NPE - modeledEntity used before initialization