Skip to main content

FreeMinecraftModels Furniture Shop

For a purchase-only economy, set registerCraftingRecipes: false in config.yml and restart. Valid enabled entries remain in the shop catalog, but are removed from Bukkit crafting and the player /fmm craftable-items menu. The setting defaults to true.

FreeMinecraftModels ships with an optional Vault-backed shop that lets players buy craftable props with in-game currency. The shop is disabled by default — it only registers itself when explicitly enabled and a Vault economy provider is available.

Quick Setup​

  1. Install Vault and a Vault-compatible economy provider (EssentialsX, CMI, etc.).
  2. Start the server once so plugins/FreeMinecraftModels/shop_config.yml is generated.
  3. Set enabled: true in shop_config.yml.
  4. Restart the server or complete a successful /fmm reload; the shop registers during full initialization.
  5. Run /fmm shop in-game to confirm the menu opens.

If any prerequisite is missing, the shop subcommand stays unregistered, so its configurable disabled message is not used through that handler. If the shop is enabled but Vault or its economy provider is missing, FMM logs a specific warning.

How It Works​

  • The shop reads recipes from plugins/FreeMinecraftModels/recipes/.
  • The shop lists loaded recipes with isEnabled: true and shopEnabled: true. Recipes load as one catalog: a YAML syntax error, two enabled recipe files for the same model_id, or a recipe the server rejects fails the whole catalog instead of dropping one entry, so check the console after /fmm reload. Registration still constructs and validates the recipe when crafting is disabled
  • Each entry uses a paper display item with the model appearance when available, a price line, a purchase prompt and its model ID. Purchases produce the model's paper placement item; this path does not create an authored weapon from its material: and enchantments
  • Clicking an entry calls PurchaseHandler, which checks the player's balance via Vault, withdraws the price, and gives the player the placement item. Items that do not fit in inventory are dropped at the player's feet.

Permissions​

PermissionDefaultDescription
freeminecraftmodels.shoptrueRequired to open the shop. Default is true so every player can browse

The permission alone does not enable the shop — enabled: true in shop_config.yml and a working economy provider are still required.

shop_config.yml​

See the Configuration page for the full key reference. The headline keys are:

  • enabled — master toggle (default false)
  • defaultPrice — default for recipes missing shopPrice; a nonpositive default falls back to 100.0. Changing it does not replace existing per-recipe prices
  • menuTitle, priceLoreFormat, clickToBuyLoreFormat — visual style
  • messages.* — five customizable feedback messages

All message strings support & color codes and the placeholders listed in the configuration reference.

Per-Recipe Fields​

Each recipe in plugins/FreeMinecraftModels/recipes/<model_id>.yml carries two shop-specific fields:

isEnabled: true
model_id: "wooden_chair"
shape:
- "L L"
- "LLL"
- "L L"
ingredients:
L: OAK_LOG
shopEnabled: true
shopPrice: 250.0
FieldDefaultBehavior
shopEnabledtrueWhen false, the recipe is hidden from purchases. Crafting still depends on recipe enablement and registerCraftingRecipes
shopPricedefaultPrice from shop_config.ymlVault currency cost when the player clicks the item

The /fmm craftify builder writes both fields on save, so adjusting price is just a text edit on the recipe file followed by /fmm reload.

Purchase Outcomes​

The PurchaseHandler recognizes seven outcomes. The first five map to configurable messages in shop_config.yml; the two delivery-failure messages are fixed:

OutcomeTriggered whenMessage key
SUCCESSWithdrawal succeeded and the item fit in inventorymessages.purchaseSuccess
SUCCESS_WITH_OVERFLOWWithdrawal succeeded but the item had to be dropped at the player's feetmessages.purchaseSuccess + messages.inventoryFull
INSUFFICIENT_FUNDSPlayer balance below price, or the underlying economy provider rejected the withdrawalmessages.insufficientFunds
NOT_FOR_SALERecipe is disabled, has shopEnabled: false, or its model is not loadedmessages.itemNotForSale
SHOP_DISABLEDThe shop config or cached Vault hook reports disabledmessages.shopDisabled
DELIVERY_FAILED_REFUNDEDWithdrawal succeeded, delivery failed, and the undelivered amount was refundedFixed: The item could not be delivered. The undelivered amount was refunded.
DELIVERY_FAILED_REFUND_PENDINGWithdrawal succeeded, delivery failed, and the refund failed or the delivered amount could not be readFixed: The purchase could not be settled. The shop has been disabled; contact an administrator to review your payment.

Use nonnegative finite shopPrice values. The purchase handler does not sanitize them before calling Vault. A rejected withdrawal response returns INSUFFICIENT_FUNDS, but provider exceptions during withdrawal are not caught here. The hook caches its provider during initialization; it does not continuously detect provider removal.

If delivery throws after the withdrawal, FMM counts how much of the purchase reached the inventory or the ground and deposits the price of the rest back. When that refund fails, or the delivered amount cannot be read, FMM disables the shop and logs [FMM Shop] Disabled after unresolved purchase with the player UUID and the amount to review. The shop stays disabled until you reconcile the payment and run /fmm reload.

Troubleshooting​

/fmm shop does not exist. The shop is unregistered. Verify all three of:

  • Vault is installed
  • An economy provider is registered (run /balance or /eco to confirm one is responding)
  • enabled: true in shop_config.yml

Then restart the server or complete /fmm reload. An importer-triggered content-only reload does not reinitialize the shop config or register its command.

Items I expect to see are missing from the menu. Open the recipe file in plugins/FreeMinecraftModels/recipes/. Check that both isEnabled and shopEnabled are true. Run /fmm reload after editing.

Players are charged but get no item. Check for an overflow item dropped at the player's feet and inspect the console around the click. A rejected withdrawal response returns INSUFFICIENT_FUNDS; an exception from the provider during withdrawal is not converted to that result. A failed delivery logs [FMM Shop] Item delivery failed with the delivered count and the refund. If the console shows [FMM Shop] Disabled after unresolved purchase, the refund did not go through: settle that payment by hand, keep the console log and provider transaction evidence, then run /fmm reload to re-enable the shop.