メインコンテンツまでスキップ

FreeMinecraftModels APIと開発者ガイド

FreeMinecraftModels is both a standalone plugin and an API surface for other plugins.

Maven Repository

<repository>
<id>magmaguy-repo-releases</id>
<name>MagmaGuy's Repository</name>
<url>https://repo.magmaguy.com/releases</url>
</repository>
<repository>
<id>magmaguy-repo-snapshots</id>
<name>MagmaGuy's Snapshot Repository</name>
<url>https://repo.magmaguy.com/snapshots</url>
</repository>

Dependency

<dependency>
<groupId>com.magmaguy</groupId>
<artifactId>FreeMinecraftModels</artifactId>
<version>LATEST.VERSION.HERE</version>
<scope>provided</scope>
</dependency>

Use it as compileOnly/provided. Do not shade the plugin into your own jar.

Core Entry Points

  • ModeledEntityManager.modelExists(String)
  • ModeledEntityManager.reload()
  • ModeledEntityManager.getAllEntities()
  • ModeledEntityManager.getDynamicEntities()
  • ModeledEntityManager.propEntities()

Core Runtime Types

  • ModeledEntity
  • StaticEntity
  • DynamicEntity
  • PropEntity

Creating Entities

StaticEntity preview = StaticEntity.create("example_model", location);
DynamicEntity mobModel = DynamicEntity.create("example_model", livingEntity);
DynamicEntity mount = DynamicEntity.createWithInvisibility("example_model", livingEntity);
PropEntity prop = PropEntity.spawnPropEntity("example_model", location);

All creation paths return null if the requested model ID is not loaded.

createWithInvisibility is a variant that applies an invisibility potion instead of hiding the entity from clients. This keeps the entity tracked client-side, which is needed for vehicle steering (used internally by /fmm mount).

Useful Runtime Methods

  • ModeledEntity#setDisplayName(String)
  • ModeledEntity#setDisplayNameVisible(boolean)
  • ModeledEntity#setLeftClickCallback(...)
  • ModeledEntity#setRightClickCallback(...)
  • ModeledEntity#setHitboxContactCallback(...)
  • ModeledEntity#setModeledEntityHitByProjectileCallback(...)
  • ModeledEntity#playAnimation(String, boolean, boolean)
  • ModeledEntity#stopCurrentAnimations()
  • ModeledEntity#hasAnimation(String)
  • ModeledEntity#getEntityID() -- returns the model ID string
  • ModeledEntity#getLocation() -- returns the current Location
  • ModeledEntity#getWorld() -- returns the World
  • ModeledEntity#getViewers() -- returns the HashSet<UUID> of players who can see the entity
  • ModeledEntity#getNametagBones() -- returns List<Bone> of nametag bones (useful for placing additional text)
  • ModeledEntity#getScaleModifier() / setScaleModifier(double)
  • ModeledEntity#removeWithDeathAnimation() -- removes with the death animation (if one exists)
  • ModeledEntity#removeWithMinimizedAnimation() -- removes with a scaling-down animation
  • ModeledEntity#remove() -- immediately removes the entity and all bones
  • DynamicEntity#setSyncMovement(boolean)
  • DynamicEntity#isDamagesOnContact() / setDamagesOnContact(boolean) -- controls whether the entity damages players via hitbox contact
  • Bone#getBoneLocation()

Event Surface

Generic interaction events:

  • ModeledEntityLeftClickEvent
  • ModeledEntityRightClickEvent
  • ModeledEntityHitboxContactEvent
  • ModeledEntityHitByProjectileEvent

Typed variants also exist for StaticEntity, DynamicEntity, and PropEntity.

Lifecycle event:

  • ResourcePackGenerationEvent -- fires when FMM finishes generating or regenerating the resource pack (on startup and on /fmm reload). Listen for this to trigger post-processing on the generated pack.

ModeledEntityHitByProjectileEvent And OBB Projectile Detection

FMM uses OBB (oriented bounding box) hit detection for projectiles against modeled entities. When a projectile intersects a modeled entity's OBB hitbox, FMM fires a ModeledEntityHitByProjectileEvent. This is a standard cancellable Bukkit event.

Key details:

  • Arrow damage is calculated with support for the POWER enchantment bonus
  • PIERCING enchantment is respected -- arrows can pass through to additional targets
  • Cancel the event to prevent damage and block the hit entirely
@EventHandler
public void onProjectileHitModel(ModeledEntityHitByProjectileEvent event) {
ModeledEntity target = event.getModeledEntity();
Projectile projectile = event.getProjectile();
// Cancel to prevent damage
event.setCancelled(true);
}

Item & Model Utilities

ModelItemFactory

Factory class for creating model-related ItemStacks programmatically.

// Create a prop placement item (uses "model_id" PDC key)
ItemStack placementItem = ModelItemFactory.createModelItem("lamp_post", Material.STICK);

// Create a custom item from config (uses "fmm_item_id" PDC key)
PropScriptConfigFields config = ItemScriptManager.getItemDefinitions().get("magic_sword");
ItemStack customItem = ModelItemFactory.createCustomItem("magic_sword", config);
  • createModelItem(String modelId, Material material) -- creates a placement item for props. On 1.21.4+, automatically applies display model rendering if a display JSON exists.
  • createCustomItem(String itemId, PropScriptConfigFields config) -- creates a custom item with name, lore, enchantments, and display model from the unified config.
  • formatModelName(String modelId) -- utility that converts a model ID like 01_em_flame_sword into Flame Sword.

DisplayModelRegistry

Simple registry that tracks which models have a display JSON available.

// Check if a model has a display model JSON registered
boolean has3D = DisplayModelRegistry.hasDisplayModel("magic_sword");
  • register(String modelId) -- registers a model ID (called internally during reload)
  • hasDisplayModel(String modelId) -- returns true if a .json display model exists for this model
  • getRegisteredModels() -- returns an immutable Set<String> of all model IDs that have display models registered
  • shutdown() -- clears all registrations

ItemScriptManager

Manages the lifecycle of per-player Lua scripts for custom items (models with material: set in their YML config).

// Get all registered custom item definitions
Map<String, PropScriptConfigFields> items = ItemScriptManager.getItemDefinitions();

// Get the active Lua script instance for a player + item
ScriptInstance instance = ItemScriptManager.getActiveScript(playerUUID, "magic_sword");

// Get all active scripts for a player
Map<String, ScriptInstance> scripts = ItemScriptManager.getActiveScripts(playerUUID);
  • scanForCustomItems(File modelsFolder) -- scans model YML configs for custom items
  • updateEquippedScripts(Player player) -- diffs equipped items against running scripts, firing equip/unequip hooks
  • removePlayer(Player player) -- shuts down all scripts for a player (call on quit)
  • getItemDefinitions() -- returns the map of item ID to PropScriptConfigFields

ScriptedItemAPI

Public API for external plugins to integrate with FMM's scripted item system. This allows other plugins to stamp their own ItemStacks with FMM scripted item data (PDC tag + item model) so that FMM's Lua script hooks fire for those items, without FMM overriding the item's name, lore, or enchantments.

// Check if a scripted item definition exists
boolean exists = ScriptedItemAPI.isValidItemId("flame_blade");

// Apply FMM scripted item data to an existing ItemStack
// This sets:
// - The fmm_item_id PDC tag (so FMM's script system recognizes the item)
// - The item model (1.21.4+) from FMM's display model registry
// Does NOT modify name, lore, enchantments, or any other item properties.
boolean success = ScriptedItemAPI.applyScriptedItemData(itemStack, "flame_blade");

// Get the config for a scripted item
PropScriptConfigFields config = ScriptedItemAPI.getItemConfig("flame_blade");
  • isValidItemId(String itemId) -- returns true if the item ID is registered in FMM's item definitions
  • applyScriptedItemData(ItemStack itemStack, String itemId) -- stamps PDC tag and item model onto an existing ItemStack. Returns true on success, false if the item ID is invalid or the ItemStack has no meta. Bow/crossbow note: if the given itemId does not have a display model but itemId + "_idle" does (i.e. the item has bow/crossbow state models), the method automatically uses the _idle model as the display model
  • getItemConfig(String itemId) -- returns the PropScriptConfigFields for the given item ID, or null if not found
EliteMobs Integration

EliteMobs uses this API internally via the scriptedItem config field. When an EliteMobs custom item sets scriptedItem: flame_blade, EliteMobs builds its item normally (name, lore, enchantments, level) then calls ScriptedItemAPI.applyScriptedItemData() to add FMM's model and script behavior on top.

PropScriptConfigFields

Unified configuration class for model YML config files. Used by both prop scripts and custom items.

# Example: torch_01.yml
isEnabled: true
scripts:
- torch_glow.lua
material: STICK # If set, model becomes a custom item
name: "&eMagic Torch" # Custom display name (optional)
lore: # Custom lore lines (optional)
- "&7Glows in the dark"
enchantments: # Enchantments (optional, format: NAME,LEVEL)
- "FIRE_ASPECT,1"

Key methods: isCustomItem(), getParsedMaterial(), getParsedEnchantments(), getScripts().

Luaスクリプティング

FreeMinecraftModels supports Lua scripts for both props and custom items through the MagmaCore 2.0 scripting engine. Script files are placed in plugins/FreeMinecraftModels/scripts/ and are bound to models via a sibling YML config next to the model file.

Prop Script Hooks

HookTrigger
on_spawnProp is spawned into the world
on_game_tickEvery tick while the prop is alive
on_zone_enterA player enters the prop's zone
on_zone_leaveA player leaves the prop's zone
on_destroyProp is removed
on_left_clickPlayer left-clicks the prop
on_right_clickPlayer right-clicks the prop
on_projectile_hitA projectile hits the prop

Item Script Hooks

Custom items (models with material: set) support 22 Lua hooks:

HookTrigger
on_equipItem enters a tracked equipment slot
on_unequipItem leaves a tracked equipment slot
on_game_tickEvery tick while the item is equipped
on_attack_entityPlayer attacks an entity while holding the item
on_kill_entityPlayer kills an entity while holding the item
on_take_damagePlayer takes damage while item is equipped
on_shield_blockPlayer blocks with a shield
on_shoot_bowPlayer shoots a bow
on_projectile_hitA projectile fired by the player hits something
on_projectile_launchPlayer launches a projectile
on_right_clickPlayer right-clicks with the item
on_left_clickPlayer left-clicks with the item
on_shift_right_clickPlayer shift-right-clicks with the item
on_shift_left_clickPlayer shift-left-clicks with the item
on_interact_entityPlayer right-clicks an entity with the item
on_swap_handsPlayer swaps the item between hands
on_dropPlayer drops the item
on_break_blockPlayer breaks a block while holding the item
on_consumePlayer consumes the item
on_item_damageItem takes durability damage
on_fishPlayer uses a fishing rod
on_deathPlayer dies while item is equipped

Item scripts receive context.item (with the item ID and player info) instead of context.prop.

Prop Script Context Table

Prop scripts receive a context table. Here is a summary of the key APIs -- see Lua Prop API for full details.

context.prop:

  • model_id -- the blueprint model name
  • current_location -- the prop's current location
  • play_animation(name, blend, loop) -- plays the named animation (blend and loop default to true)
  • stop_animation() -- stops all current animations
  • hurt_visual() -- plays the hurt (red flash) visual on the prop
  • pickup() -- removes the prop and drops its placement item
  • mount(player) -- makes a player ride the prop
  • dismount(player) -- removes a player from the prop
  • get_passengers() -- returns a list of players currently riding the prop
  • spawn_elitemobs_boss(filename, x, y, z) -- spawns an EliteMobs boss relative to the prop

context.event:

  • Available in on_left_click, on_right_click, and on_projectile_hit
  • cancel(), uncancel(), is_cancelled
  • player -- the player who triggered the event

context.world:

  • spawn_entity(entity_type, location) -- spawns a vanilla entity
  • set_block_at(location, material) -- sets a block in the world
  • Plus particles, sounds, block queries, lightning, and nearby-entity lookups

Player objects (from context.event.player):

  • get_held_item() -- returns the item the player is holding
  • consume_held_item() -- removes one of the held item
  • has_item(material) -- checks if the player has an item
  • send_message(text) -- sends a chat message to the player
  • game_mode -- the player's current game mode

Prop Script Example

function on_spawn(context)
context.prop.play_animation("idle", true, true)
end

function on_right_click(context)
context.prop.play_animation("activate", false, false)
end

Item Script Example

function on_equip(context)
context.event.player.send_message("&6You equipped the Flame Blade!")
end

function on_attack_entity(context)
-- Fire effect on hit
context.event.player.send_message("&cBurn!")
end

function on_unequip(context)
context.event.player.send_message("&7Flame Blade sheathed.")
end

注意事項

  • FreeMinecraftModels is an installed-plugin dependency, not an embeddable library.
  • If your plugin needs freshly imported models, call ModeledEntityManager.reload() instead of trying to rebuild FreeMinecraftModels state yourself.
  • All plugins in the Nightbreak ecosystem now depend on MagmaCore 2.0.0-SNAPSHOT, which includes the shared Lua scripting engine used by FreeMinecraftModels prop scripts and EliteMobs Lua powers.