Skip to content

Repository files navigation

BetterModel

- Modern Bedrock model engine for Minecraft Java Edition -



(In BlockBench / In Minecraft)

✨ Introduction

BetterModel is a server-based engine that provides runtime BlockBench model rendering & animating for Minecraft Java Edition.

  • Built on the item-display packet.
  • Implements essential BlockBench elements, including cubes, meshes, null objects, and locators.
  • Support for model animations, Molang expressions, and IK (Inverse Kinematics) rigging.
  • Supports player skin models and custom armor.
  • Automated resource pack generation with zero reliance on core shaders.
  • Provides support for entity syncing.
  • Extensible API available for integration.
In-Game Screenshots




🚀 Key Features & Focus

BetterModel aims to be a reliable engine that provides stable, high-quality animations for Paper-based high-traffic servers.

  • Stability First: We take a conservative approach to feature expansion. By avoiding the implementation of features that are difficult to maintain or have limited use cases, we focus on providing a stable API and ensuring overall operational safety.
  • Performance Optimized: Our goal is to minimize runtime computation, memory footprint, and network overhead. Through asynchronous design and optimized packet handling, we ensure the engine runs efficiently even under heavy server loads.
  • Tailored for Large-scale Servers: We provide essential features specifically designed for high-population servers and MMORPG content creation.
    • Per-player Animation: Individual animation control tailored to each player's perspective.
    • Player Model Animation: Support for sophisticated 12-limb animations based on player models.

📚 Wiki

🛠️ Build info

Build

./gradlew build: Builds all jars
./gradlew shadowJar: Builds plugin jar
./gradlew javadocJar: Builds Javadoc jar
./gradlew runServer: Runs Paper test server with test plugin

Library

Tested Bukkit Server Platform

Tested Mod Server Platform

💻 API

Note

For more detailed API specifications, please refer to our GitHub Wiki.

Gradle (Kotlin)

Release

repositories {
mavenCentral()
maven("https://maven.blamejared.com/") // For transitive dependency in bettermodel-fabric
maven("https://maven.nucleoid.xyz/") // For transitive dependency in bettermodel-fabric
}
dependencies {
compileOnly("io.github.toxicity188:bettermodel-bukkit-api:VERSION") // bukkit(spigot, paper, etc) api//api("io.github.toxicity188:bettermodel-fabric:VERSION") // mod(fabric)
}

Snapshot

repositories {
maven("https://maven.pkg.github.com/toxicity188/BetterModel") {
credentials {
username =YOUR_GITHUB_USERNAME
password =YOUR_GITHUB_TOKEN
}
}
maven("https://maven.blamejared.com/") // For transitive dependency in bettermodel-fabric
maven("https://maven.nucleoid.xyz/") // For transitive dependency in bettermodel-fabric
}
dependencies {
compileOnly("io.github.toxicity188:bettermodel-bukkit-api:VERSION-SNAPSHOT") // bukkit(spigot, paper, etc) api//api("io.github.toxicity188:bettermodel-fabric:VERSION-SNAPSHOT") // mod(fabric)
}
Gradle (Groovy)

Release

repositories {
mavenCentral()
maven 'https://maven.blamejared.com/'// For transitive dependency in bettermodel-fabric
maven 'https://maven.nucleoid.xyz/'// For transitive dependency in bettermodel-fabric
}
dependencies {
compileOnly 'io.github.toxicity188:bettermodel-bukkit-api:VERSION'// bukkit(spigot, paper, etc) api//api 'io.github.toxicity188:bettermodel-fabric:VERSION' // mod(fabric)
}

Snapshot

repositories {
maven {
url "https://maven.pkg.github.com/toxicity188/BetterModel"
credentials {
username =YOUR_GITHUB_USERNAME
password =YOUR_GITHUB_TOKEN
}
}
maven 'https://maven.blamejared.com/'// For transitive dependency in bettermodel-fabric
maven 'https://maven.nucleoid.xyz/'// For transitive dependency in bettermodel-fabric
}
dependencies {
compileOnly 'io.github.toxicity188:bettermodel-bukkit-api:VERSION-SNAPSHOT'// bukkit(spigot, paper, etc) api//api 'io.github.toxicity188:bettermodel-fabric:VERSION-SNAPSHOT' // mod(fabric)
}
Maven

Release

<repositories>
<repository>
<id>central</id>
<url>https://repo.maven.apache.org/maven2</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>io.github.toxicity188</groupId>
<artifactId>bettermodel-bukkit-api</artifactId>
<version>VERSION</version>
<scope>provided</scope>
</dependency>
</dependencies>

Snapshot

<repositories>
<repository>
<id>github</id>
<url>https://maven.pkg.github.com/toxicity188/BetterModel</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>io.github.toxicity188</groupId>
<artifactId>bettermodel-api</artifactId>
<version>VERSION-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.github.toxicity188</groupId>
<artifactId>bettermodel-bukkit-api</artifactId>
<version>VERSION-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
</dependencies>
Example code

Gets some model or limb

BetterModel.model("demon_knight"); //A model file in BetterModel/models (for general model with saving)BetterModel.limb("steve"); //A model file in BetterModel/players (for player model with no saveing)BetterModel.modelOrNull("demon_knight"); //general model or nullBetterModel.limbOrNull("steve"); //player model or null

Creates model (entity)

EntityTrackertracker = BetterModel.model("demon_knight")
.map(r -> r.getOrCreate(BukkitAdapter.adapt(entity))) //Gets or creates entity tracker by this renderer to some entity.
.orElse(null);
EntityTrackertracker = BetterModel.model("demon_knight")
.map(r -> r.create(BukkitAdapter.adapt(entity), TrackerModifier.DEFAULT, t -> t.update(TrackerUpdateAction.tint(0x0026FF)))) //Creates entity tracker with pre-spawn task.
.orElse(null);

Creates model (dummy)

DummyTrackertracker = BetterModel.model("demon_knight")
.map(r -> r.create(BukkitAdapter.adapt(location))) //Creates some dummy tracker to this location.
.orElse(null);
DummyTrackertracker = BetterModel.limb("steve")
.map(r -> r.create(BukkitAdapter.adapt(location), ModelProfile.of(BukkitAdapter.adapt(player)))) //Creates some dummy tracker to this location and player's skin profile.
.orElse(null);

Update some tracker's display data

BetterModel.model("demon_knight")
.map(r -> r.create(BukkitAdapter.adapt(entity), TrackerModifier.DEFAULT, t -> {
t.update(TrackerUpdateAction.tint(rgb)); //Tintt.update(TrackerUpdateAction.enchant(true), bone -> true); //Enchant with predicate
}))
.ifPresent(tracker -> tracker.update(TrackerUpdateAction.composite( //CompositeTrackerUpdateAction.brightness(15, 15) //BrightnessTrackerUpdateAction.billboard(Display.Billboard.CENTER) //Billboard
)));
}

💬 Community

💖 Support

About

Modern Bedrock model engine for Minecraft Java Edition

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages