DBetterModel
6.1.0Adds interop between BetterModel and Denizen! One jar for every BetterModel (1.15.x, 2.x, 3.x).
6.1.0latestDBetterModel 6.1.0 | BM 1.15.x / 2.0.x–2.2.x / 3.0.x–3.3.xJul 20, 2026 <div align="center"> DBetterModel 6.1.0: BetterModel 3.3.0 support. </div> A maintenance release that compiles the v3 compat layer against BetterModel 3.3.0 while keeping the single universal jar working on every earlier BM line. No script, command, tag, or mechanism changed — every 6.0 script runs unchanged. | BetterModel | DBetterModel | |---|---| | 1.15.x / 2.0.x–2.2.x / 3.0.x–3.3.x | 6.1.0 (this jar) | Breaking changes: none.What changed
- Build against BetterModel 3.3.0 —bettermodel.v3.versionbumped 3.2.0 → 3.3.0, so the v3 layer compiles against the current API. - Migrated off the deprecated manager getters — BM 3.3.0 refactored the per-manager accessors (modelManager(),scriptManager(),skinManager(), …) into a singleBetterModelPlatform#manager(Class)and marked the old getters@Deprecated(removal candidates in a future major). The v3 layer now goes through the unified accessor.Why it needed a runtime fork, not a swap
BM 3.3.0 didn't just rename methods — it split the API: - 3.2.0 and below: only the named getters exist. There is noManagersupertype and nomanager(Class)method. - 3.3.0+:manager(Class)is the real accessor; the named getters became deprecated delegates, slated for removal in 4.x. DBetterModel ships one jar that selects a compat layer at startup and must keep running on 3.0.x–3.3.x (and best-effort 4.x). A static call tomanager(Class)wouldNoSuchMethodErroron a 3.2.0 server; relying only on the getters would break on 4.x once they're removed. So the newV3Managershelper resolves the accessor reflectively at load time — preferringmanager(Class)on 3.3.0+ and falling back to the named getter on 3.2.0 — the same idiom the v2 layer already uses to bridge a BM API break (V2HitboxLegacy).Compatibility
- BetterModel 3.3.0 — new, via the unifiedmanager(Class)accessor. - BetterModel 3.0.x–3.2.x — unchanged; served through the legacy-getter fallback. - BetterModel 1.15.x / 2.x — untouched (v1/v2 layers).Testing
Verified on a live in-game headless stand against BetterModel 3.3.0, plus the unit suite, all green. Automated —tests/minecraft/test-headless.dsc(console-driven, spawns its own rig,DBM-RESULT OK/FAILline): | BM | Layer | Server / Java | Result | |---|---|---|---| | 3.3.0 | v3 | Paper 26.2 / Java 25 | 19/19 | Run against a real BetterModel 3.3.0 server with Denizen 1.3.3-SNAPSHOT (build 7290-DEV) and the stockdemon_knight/blue_wizard/stevemodels. The console reportedDetected BetterModel 3.3.0 — using compat layer …V3Platform— which prints only after theV3Platformconstructor (and thus the migratedmanager(Class)path) succeeds — followed byDBM-RESULT OK=19 FAIL=0, with noNoSuchMethodErroror manager exceptions in the log. Unit —LayerSelectorTest,VersionsTestgreen, including a new assertion that 3.3.0 resolves to the v3 layer../gradlew build importBanpasses: the v3 layer compiles againstbettermodel-*-api:3.3.0, and the compat boundary check (:coremust not touch a BM class) still holds. Unchanged lines — the v1 (1.15.x) and v2 (2.x) layers are byte-for-byte unchanged from 6.0.0, and the v3 path for 3.0.x–3.2.x now runs through the legacy-getter fallback; their 6.0.0 headless results (19/19 each on 3.2.0, 3.0.1, 2.2.0, 2.0.1, 1.15.2) carry over.Requirements
Java 21+ (Java 25 only when running BetterModel 3.x — BM 3.x itself requires it) · Paper 1.21.x+ · Denizen 1.3.1+. Docs: [wiki.meigo.pw/docs/dbettermodel](https://wiki.meigo.pw/docs/dbettermodel) and the in-repo [docs/](https://github.com/meigoc/DBetterModel/tree/main/docs) folder. Full Changelog: https://github.com/meigoc/DBetterModel/compare/v6.0.0...v…6.0.0DBetterModel 6.0.0 | BM 1.15.x / 2.0.x–2.2.x / 3.xJul 11, 2026 <div align="center"> . </div> One jar for every BetterModel. 6.0 detects the installed BetterModel at startup and selects the matching compat layer — the per-BM-version release matrix of 5.x is gone. | BetterModel | DBetterModel | |---|---| | 1.15.x / 2.0.x–2.2.x / 3.x | 6.0.0 (this jar) | Breaking changes: none. Every 5.0 script runs unchanged.Highlights
- Universal compat core — three statically compiled layers (v1/v2/v3), selected by BetterModel version at startup. Public BM API only, no private-field reflection. Future BM 4.x gets a best-effort probe instead of a crash. - Capability system — scripts query what the running BetterModel supports via<bm.capabilities>; unavailable features report clean errors, never stacktraces. - Blockbench keyframe signals —denizen:name{key=value}instruction keyframes fire thebm animation signalevent on all supported BM lines, including 1.15.x and 2.x. - `bmsummon` — location-bound models (dummy trackers) for props and cutscenes. - Read/write bone API — 5.x write-only display state (glow, tint, billboard, view range, brightness, scale, offset, item) now reads back. - Legacy aliases restored —world_rotation, bonebm_entity,lerp_frames— pre-5.0 scripts work again.New in the Denizen surface
- Command:bmsummon [model:<model> location:<location>] / [handle:<bmmodel> remove](withsave-entrysummoned_model). - Server tags:<bm.version>,<bm.compat_layer>,<bm.capabilities>,<bm.models>,<bm.limbs>. - Events (joining the existingbm starts/finishes reload):bm animation signal,bm player animation signal,bm animation starts,bm animation ends,bm model spawns for player,bm model despawns for player,bm tracker created,bm tracker closed,bm hitbox damaged,bm hitbox interacted,bm model mounted,bm model dismounted. - Mechanism:skinon BMBoneTag —- adjust <[bone]> skin:[part=head;from=<player>], the modern take onbmpart(which stays supported). - Tags: bone getters (glow,glow_color,tint,billboard,view_range,brightness,shadow_radius,scale,offset,item),<BMBoneTag.skin_parts>,<BMModelTag.viewers>,<BMModelTag.running_animations>,<context.model>on signal events,bmmodel@dummy:<id>,<model>identity form for summoned models.Experimental (see [docs/EXPERIMENTAL.md](https://github.com/meigoc/DBetterModel/blob/main/docs/EXP…
- Keyframe script bridge —denizen:run{script=knight_strike;damage=8}on a Blockbench keyframe starts the named task script with the metadata as definitions. Toggle:experimental.keyframe-script-bridge. - Folia readiness — all internals are region-safe and the jar declaresfolia-supported: true. Waiting on Denizen's own Folia support to matter on vanilla Folia; works today on force-load forks.Fixed 5.x bugs
- Bone mechanisms fired their fulfill twice when applied via BMModelTag — now exactly once. -rotatemechanism accumulated rotation modifiers on repeated writes — now replaces. - Debug errors could be swallowed when the debug flag was off — errors always reach the console now. - Update checker rewritten: proper JSON parsing of/releases/latest, failures logged instead of ignored.DBetterModel vs denizen-utilities (BetterModel bridge)
Both bridge BetterModel into Denizen. Verified against denizen-utilities 2.8.x (BetterModel bridge, compiled againstbettermodel-bukkit-api:3.0.1): | | DBetterModel 6.0 | denizen-utilities | |---|---|---| | BetterModel support | 1.15.x + 2.x + 3.x, one jar | 3.x only | | BM API access | public API only | reflection into a BM private field (RenderedBone.itemStackviagetDeclaredField/setAccessible) | | Off-thread work | Bukkit/region schedulers | a rawnew ThreadwithThread.sleep(100)| | Keyframe signals (bm animation signal) | fire on all BM lines, incl. 1.15/2.x | 3.x only | | Location-bound models (dummy trackers) | yes —bmsummon| no | | Skin part → bone |bmpartcommand andskinmechanism, resolved via BetterModel's tracked profile |.skinmechanism (theirbmpartis deprecated) | | Mount / billboard | commands (bmmount,bmboard) | mechanisms (.mount,.billboard) | | Compat safety | build fails if:coretouches a BM class; per-version layers | single build against one BM API | denizen-utilities is a capable, actively documented bridge; the table lists only differences that are verifiable in its source, not a quality judgement.Testing
Verified on five automated headless stands + one manual in-game session, all green. Automated —tests/minecraft/test-headless.dsc(console-driven, spawns its own rig,DBM-RESULT OK/FAILline): | BM | Layer | Server / Java | Result | |---|---|---|---| | 3.2.0 | v3 | Leaf 26.2 / Java 25 | 19/19 | | 3.0.1 | v3 | Leaf 26.1.2 / Java 25 | 19/19 | | 2.2.0 | v2 | Paper 1.21.10 / Java 21 | 19/19 | | 2.0.1 | v2 (reduced) | Paper 1.21.4 / Java 21 | 19/19 | | 1.15.2 | v1 | Paper 1.21.10 / Java 21 | 19/19 | Manual —tests/minecraft/test.dsc(in-game, visual + event checks): BetterModel 3.2.0 · Denizen 1.3.3-SNAPSHOT (build 7290-DEV) · SkinsRestorer 15.12.4 · Leaf 26.2 (build 17) · DBetterModel 6.0.0. All commands, tags, mechanisms, per-player animation events and keyframe signals confirmed.Requirements
Java 21+ (Java 25 only when running BetterModel 3.x — BM 3.x itself requires it) · Paper 1.21.x+ · Denizen 1.3.1+. Docs: [wiki.meigo.pw/docs/dbettermodel](https://wiki.meigo.pw/docs/dbettermodel) and the in-repo [docs/](https://github.com/meigoc/DBetterModel/tree/main/docs) folder. Full Changelog: https://github.com/meigoc/DBetterModel/compare/v5.0.0...v…5.0.0DBetterModel 5.0.0 | BM v1.15.0Dec 25, 2025 Feat
- Added bStats metrics integration. - Addedshadow_radiusmechanism to control bone shadow size. - Addedbillboardmechanism support directly toBMBoneTag. - New tags:<BMBoneTag.local_position>and<BMBoneTag.real_position>. -BMModelTagnow accepts mechanisms (tint, glow, etc.) to apply changes to the entire model at once.Refactor
- Optimizedbmpartcommand: skins now load asynchronously and apply immediately (removed artificial delay). - Updated<BMBoneTag.global_position>to return a standardLocationTag. - Improved internal rendering logic for better compatibility with BetterModel API. - Removed forced skin cache clearing to improve performance.4.3.0DBetterModel 4.3.0 | BM v1.14.0Nov 2, 2025 Added:
- BetterModel 1.14.0 support4.2.0DBetterModel 4.2.0 | BM v1.13.4Oct 19, 2025 Added:
- BetterModel 1.13.4 supportBug Fixes
bmmount:* Fixed a command argument parsing error that caused a "Too many linear arguments" failure when executing the command. bmmount:* Refactored the entire command logic to use the BetterModel API directly for mounting and dismounting entities from model bones. * This resolves the core issue where the command would appear to succeed but had no effect. * The command now correctly retrieves theRenderedBoneand itsHitBoxto perform mount/dismount actions. * Added proper error handling to inform the user if the target bone is not a valid seat (i.e., not tagged withpin the model file).4.1.0DBetterModel 4.1.0 | BM v1.13.0Oct 8, 2025 Added:
-<PlayerTag.limb>: Returns the MapTag of the player’s limb animation data. Example:map@[animation_name=roll;loop_mode=loop;default_loop_mode=play_once]-<PlayerTag.limb_bones[<model_name>]>: Returns the MapTag of all player limb bones. - BetterModel 1.13.0 support3.4.0DBetterModel 3.4.0 | BM v1.10.2Jul 30, 2025 Fixed:
- Resolved a critical state management issue where applying transformations to a bone (e.g.,scale,item,offset) would reset any previously applied transformations. The bone's state is now persistent across separate commands, allowing for cumulative adjustments.Added:
- New `offset` Mechanism: Added anoffsetmechanism toBMBoneTag. This allows scripters to apply a local positional offset to a bone using aLocationTagwithout altering its currently displayed item or scale. Syntax:adjust <bone> offset:<location>. - New `view_range` Mechanism: Added aview_rangemechanism toBMBoneTag. This allows scripters to set the render distance of a bone's display entity in blocks, using a decimal value. This is useful for hiding model parts in certain camera perspectives. Syntax:adjust <bone> view_range:<#.#>.Changed:
- Theitemmechanism forBMBoneTaghas been refactored. It no longer accepts aLocationTagfor an offset. Its sole purpose is now to set theItemTagfor the bone, preserving any existing offset or scale.3.2.0DBetterModel 3.2.0Jul 27, 2025 Refactored:
- Extracted core bone manipulation logic fromBMBoneTaginto the newnet.openproject.dbettermodel.api.BMBoneAPI class. This significantly reduces complexity in the Denizen object layer, improves code structure, and enhances reusability. - SimplifiedBMBoneTagto act as a lightweight proxy, delegating all mechanism logic (tint, visible, item) to the newBMBoneAPI.Added:
- New API Class: Introducednet.openproject.dbettermodel.api.BMBone, a high-level API for programmatic control over individual model bones. It provides simplified methods for tinting, visibility (global and per-player), item setting, and scaling. - New Mechanism: Added ascalemechanism toBMBoneTag. This allows scripters to adjust the non-uniform scale of a bone's displayed item using aLocationTagas a vector. - New Command Argument: Added an optionalhide:<player>argument to thebmlimbcommand. This allows hiding all of the target player's active models from a specific observer player.Changed:
- Updated the syntax of thebmlimbcommand to include the new optionalhideargument. - ModifiedBMLimbCommand'sprocessing logic to interact with the target player'sEntityTrackerRegistryto apply per-player visibility changes when thehideargument is used.3.1.0DBetterModel 3.1.0 | BM v1.10.1Jul 26, 2025 for BetterModel v1.10.1, MC 1.21.4, Denizen 1.3.1 (7144)Added:
- Bone Visibility Mechanism (`visible`): Implemented a new mechanism forBMBoneTagto control bone visibility. It supports both global toggling and per-player visibility changes via packet manipulation. [EXPERIMENTALLY, THERE ARE PROBLEMS] - Bone Item Mechanism (`item`): Introduced a mechanism forBMBoneTagthat allows setting a customItemTagas the bone's model, with optional support for a localLocationTagoffset. [This mechanism previously existed, but has been added again] - Configurable Skin Application Delay: Introduced a new option inconfig.yml(options.skin-apply-delay-ticks) to allow server administrators to define the delay before a player skin part is applied to a model bone via thebmpartcommand. This provides greater flexibility and control over the timing of asynchronous operations, enabling fine-tuning for server performance and skin-fetching reliability. - Dynamic Skin Part Command (`bmpart`): Implemented the newbmpartcommand to interface with BetterModel's skin and bone APIs. This command allows scripts to map a model bone to a player's skin part (e.g., head, arm), enabling dynamic model customization. The feature utilizes a customBoneItemMapperin conjunction withSkinManager#removeCacheto ensure skin textures are fetched and applied correctly, even when updated in real-time by other plugins. - SkinsRestorer Hook, new debug, new config and more
Similar projects
Plugin →VeinMiner
Mine the whole vein on mining a single ore/block. Make the tedious mining experience to something satisfying and fun! FTB Ultimine alternative
99.3MSueta
Simple Voice Chat
A working voice chat in Minecraft!
76.8MSueta
Chunky
Pre-generates chunks, quickly and efficiently
18.4MSueta
VeinMiner Enchantment
Veinminer Addon - Adds vineminer enchantment to enchanting tables. Only tools with the enchantment can veinmine
18MSueta
JourneyMap
Real-time map used for mapping in-game or your browser as you explore.
14.7MSueta
WorldEdit
A Minecraft Map Editor... that runs in-game! With selections, schematics, copy and paste, brushes, and scripting. Use it in creative, or use it temporarily in survival.
11.6MSueta