Shops Extension is a commerce system for TypeWriter, engineered for BTC Studio infrastructure. It provides a full-featured shop experience with dynamic pricing and stock handling.
- Dynamic & Fixed Pricing: Prices that fluctuate based on supply and demand, or stay fixed.
- Barter (items for items):
priceMode: ITEMSsells an article against one or several items instead of currency — "1 enchanted book for 12 copper ingots and 3 kelp". See Prices paid in items. - Categories & Item Pools: Organize offers into categories, with randomized item pools.
- Stock Management: Real-time tracking of shop stock levels.
- Per-Player Stock (
perPlayer): every player has their own stock of each item; a purchase only lowers the buyer's stock and a reset refills everyone's. Limits keep their own scope. - Per-Player & Global Limits: Buy/sell limits per player and globally.
- Taxes & Promotions: Global and per-item taxes, price trends, and promotions.
- Shop-wide defaults:
defaultNameFormat/defaultLoreFormatapply to every item that declares no name or lore of its own. An item that declares one keeps it untouched. - Tokens:
{item},{buy},{sell},{stock},{stock_max},{currency},{item_price}. A lore line asking for an unavailable price is dropped instead of rendering empty.
- Set
priceMode: ITEMSon an item and list what it costs initemPrice— eachItemCostis an item plus a quantity per unit bought. Several lines mean several items are required at once; several units multiply every line. defaultItemPriceon the shop applies to everyITEMSarticle that declares noitemPrice. An article's own list replaces the shop's, it is never added to it.- An
ITEMSarticle with no price anywhere is a configuration mistake, not a free article: the purchase is refused, the reason is logged, nothing is delivered. - The player pays with what the inventory holds; a catalogue item is matched by its identity, not only by its material. What is missing is computed before anything is removed, so a refused purchase never consumes part of the price. Space for the bought item is checked before the withdrawal too: a barter has no refund.
- Refusals use
cannotAffordItemsMessagewith{missing}("3 × Kelp, 12 × Copper Ingot") and{amount}. "Buy max" buys as many units as the inventory can pay for. - Show the price with the
{item_price}token: one line per requested item,- 12 × Copper Ingot.{buy}and{sell}lines are dropped on such an article, and thebuy_price/sell_priceplaceholders read—. - An
ITEMSarticle cannot be sold back for currency: its sell price is zero.
ShopTransactionEvent: fired once a purchase or a sale has completed. Other extensions — a Discord relay, an audit log, an analytics pipeline — plug in here without Shops knowing they exist. Announced after the fact, so it carries no cancellation.notificationWebhookId: the id a shop author writes on the definition. Shops does not resolve it and does not know what a webhook is; it travels on the event for whoever handles Discord.- A listener that throws is reported and the transaction stands: nothing undoes a purchase that has already been paid for and delivered.
- Full GUIExtension Integration: Customizable layouts via the GUI/OmniGUI extension.
- Buy/Sell Toggles: Configurable per item.
sellAllEnabledoff refuses the sell-all action with the shop'scannotSellMessage. - Live stock refresh:
defaultRefreshTicks(shop, default 20; 0 = no automatic check) and the item'srefreshTicksredraw an open shop when the stock shown changes (finite stocks only). - Fixed slots: an item's
guiSlotpins it at a fixed slot of the content area on every page; an item that cannot be placed is moved to a free cell or reported in the console. - Transaction History: Persistent storage via artifact.
| Entry | Id |
|---|---|
| Shop Definition | shop_definition |
| Shop Category | shop_category |
| Item Pool | item_pool |
| Shop Promotion | shop_promotion |
| Shop Artifact (runtime storage) | shop_artifact |
| Open Shop (action) | open_shop |
- List and inspect loaded shop definitions.
- Open, refresh and close a shop session for an online player.
- Reset runtime stock and limits for a shop.
- Inspect and mutate stock for direct shop items.
- Inspect the latest transactions recorded for a player.
Shops Extension configuration is managed via TypeWriter's manifest system.
Requirements: Typewriter 0.9.0-beta-177 on Paper, and the GUI extension (renaud:GuiAndDialogs,
OmniGUI). Vault (economy) and
PlaceholderAPI are used when present.
Requires Java 21.
# Clone the repository
git clone https://github.com/RenaudRl/AdvancedShopsExtension.git
cd AdvancedShopsExtension
# Build the project
./gradlew clean buildbuild/libs/TypeWriter-ShopsExtension-[Version].jar
| Command | Permission | Description |
|---|---|---|
/tw shop <id> |
typewriter.shop.open |
Open a shop. Available to players by default. |
/tw shop admin |
typewriter.shop.admin |
Show operator tools. OP-only by default. |
/tw shop admin list |
typewriter.shop.admin |
List loaded shops. |
/tw shop admin info <shop> |
typewriter.shop.admin |
Inspect shop and direct-item indexes. |
/tw shop admin open <shop> [target] |
typewriter.shop.admin |
Open a shop for a player or selector target. |
| `/tw shop admin refresh | close [target]` | typewriter.shop.admin |
/tw shop admin reset <shop> |
typewriter.shop.admin |
Reset runtime stock and limits. |
| `/tw shop admin stock get | set | add |
/tw shop admin history [target] |
typewriter.shop.admin |
Show the latest runtime transactions. |
- TypeWriter - The engine this extension is built for.
- BTC Studio - Maintenance and specialized optimizations.
Full documentation available at BTC Studio Docs.
GNU General Public License v3.0 or later — LICENSE — with a linking exception for the Typewriter engine — LICENSE-EXCEPTION.md.
| You may | Run it anywhere, including on a monetised server. Study it, modify it, use it as a base, and redistribute it — even for a fee. GPLv3 §4 explicitly allows charging for a copy. |
| You must | Publish the complete corresponding source of your version under GPLv3, preserve the copyright notices, and state that you modified it and when (§5(a)). |
| You may not | Ship a closed-source or proprietary version, relicense under stricter terms, or strip the attribution and present this work as your own — §8 terminates your rights automatically. |
| Marks | "Born To Craft" and "BTC Studio" are not covered by the GPL. Fork it freely, sell your fork if you like — but rebrand it. |
Reselling this code is legally allowed and practically pointless: whoever buys a copy from you receives, under the GPL, the right to redistribute it for free. That is the protection — not a clause forbidding sale, which the GPL does not permit us to add.
This is a third-party extension. It uses the public extension API of the Typewriter engine by gabber235 and contains none of its source. Born To Craft Studio is not affiliated with or endorsed by the Typewriter project.
The engine itself is not free software — its licence forbids redistributing it. Get it from the Typewriter project, and never redistribute it, including inside a fork of this repository.
Full attribution, the statement of modifications required by §5(a), and the trademark reservation are in NOTICE.md. Read it before redistributing.
© 2026 Born To Craft Studio.