Skip to main content
KiteMarket provides the complete vanilla GUI plus ItemsAdder v4 compatibility. Third-party developers may freely create, modify, use, distribute or independently sell their own configuration or Java interfaces without an additional KiteMC theme license. Public SDKs and examples have independent MIT licenses; IA theme resources are not bundled.
Version and downloadsThis page covers the 1.0.0 public UI SDK. Interface source and examples are available through the public repository; see downloads for runtime, SDK and example filenames. The pinned Paper 1.21.11 / Java 21 / ItemsAdder 4.0.16 combination has real openings of community configuration and Java examples; the recorded scope does not certify other versions or Folia.

Quick start

For vanilla appearance changes, use file configuration without writing a plugin. A built-in IA renderer only needs your resources and theme declaration; use Java only for custom rendering logic.
  1. Get the examples/ui/themes/example-ia configuration example from the public repository, or the Java IA example in KiteMarket-Examples-1.0.0.zip once released.
  2. Follow IA integration to install your namespace and theme, rebuild the pack and register its actual UUID and SHA-1.
  3. Java providers also require their JAR in plugins/ and a normal restart. Configuration-only themes use /km reload.
  4. After the player successfully applies the pack, use /km ui itemsadder example-ia; the Java example theme is example-ia-java. Confirmation buttons act on the real market, so develop with isolated characters and orders.

Java example: GitHub Packages

Reference com.kitemc:kitemarket-ui-api:1.0.0 with compileOnly, never bundling or relocating the SDK. Runnable source is in the public examples/ui-java project, without proprietary core dependencies. First merge the market API’s Packages registry and authentication configuration, then add these dependencies. Public packages also need a classic PAT with read:packages, provided through user-level gpr.user/gpr.key or GITHUB_ACTOR/GITHUB_TOKEN. Never store tokens in the project. Confirm that the repository’s Packages list contains the version before using it; this guide does not claim the package is already uploaded.
For Maven, use the same github-kitemarket registry and settings.xml credentials, then add:
Retain the Paper/Bukkit and IA API compile dependencies and their own registries. Packages do not contain vendor runtime plugins. Both SDKs remain Java 11; the real IA adapter example remains Java 21. For offline development or when Packages authentication is unavailable, download KiteMarket-UI-API-1.0.0.jar directly from GitHub Releases as a fallback compile dependency without a Packages Token. No reference method allows bundling, shading or relocating the SDK.

Player selection and server defaults

/km ui displays the requested preference, actual interface, theme, and fallback reason. Select a backend and optional theme with:
Selection stores a preference. Without an actual provider, ready client, or resources, vanilla remains available with an explanation. “Choose a theme” in the settings lists registered themes with their backend and availability reason and can restore the server default. Preferences persist across the market network. Switching retains drafts and cannot submit a trade twice. For example:
Player buttons, command help and completion show only auto/vanilla/itemsadder. Old germ/dragoncore preferences, settings and SDK enums remain readable as existing extension positions. Developers may register, maintain and validate their own actual providers. Without a matching registered provider, the interface reports UI_BACKEND_RETIRED, falls back and retains the saved preference.

Own theme declarations

Place declarations in plugins/KiteMarket/themes/*.yml and validate/load them with /km reload; an invalid candidate retains the active catalog. IDs use lowercase letters, digits, dots, underscores and hyphens, up to 96 characters, beginning with a letter or digit. official.* and the km_market_stall namespace are reserved identifiers. Third parties should use their own IDs and namespaces.
This is KiteMarket’s common theme format, not a vendor-native configuration. provider is the stable ID of an actually registered implementation; omitting it does not create an SDK bridge. pages.'*' supplies defaults for shared pages, including themes; a specific template ID overrides font and title/background offsets. The table below distinguishes page IDs from template IDs: supply-preview uses the supply template. Actual items, amounts, results and actions remain server-owned. state-font-images selects artwork from the server’s result.status: SUCCESS, PENDING, FAILED and UNCONFIRMED describe completion, review required, refusal and an unconfirmed outcome. These presentation values are distinct from ledger operation states. A page mapping takes precedence over a resource-level state mapping; absent mappings use the page/general background. An exact page declaration is used when present, otherwise *; omitted font/offset fields use resources/config defaults. The built-in ItemsAdder provider is kitemarket.itemsadder. Third-party themes may reference their own registered font IDs, such as km_example:market, without a theme product ID or entitlement receipt. requires: {} omits pack fields and inherits node defaults. For a separate pack, add its actual lowercase SHA-1 (40 digits) and sent UUID as requires.pack-sha1 and pack-id. Empty strings fail theme validation. Missing valid identity or an unsuccessfully applied pack falls back. Updated content requires a new actual sent UUID; a registered UUID cannot be assigned a different digest. Readiness uses public ProtocolLib observations of actual UUID, SHA-1 and URL, correlated with IA’s public send event; it does not call internal obfuscated classes or treat a send event alone as readiness. Temporarily enable gui.itemsadder.diagnostics: true to inspect [KITEMARKET_PACK], then disable it after registering identity. Failure, discard or removal revokes only that pack, leaving unrelated loaded IA state intact. Disconnects, node changes, removal of every pack or IA reload require confirmation again. Native status messages carry no send generation, so delayed responses to a repeated UUID with identical content cannot be distinguished by the protocol; changed content must use a fresh actual UUID.

Resources and provider implementations

  • ItemsAdder: Maintain your own namespace, manually rebuild and send the pack, and register its actual SHA-1 and Minecraft pack UUID. Sending a pack does not mean it has loaded. Market items remain actual ItemStacks; font images decorate standard inventories.
  • Java extensions: Register your own provider through the public SDK and maintain its actual engine, resources and thread compatibility. Compatibility enum values do not imply that the base plugin bundles the corresponding vendor adapters.
Providers render and capture input; the shared server controller handles transactions. Callbacks must use server-registered action/input identifiers, never client-supplied amounts, identities, or stale pages. Closing pages, expiry, and repeated confirmations retain the shared session safeguards. The public KiteMarket-UI-API module targets Java 11 under its own MIT License. Reference it with compileOnly, never bundling a second SDK. Implement com.kitemc.market.api.ui.UiProvider, obtain KiteMarketUiApi through Bukkit’s ServicesManager, and call api.register(owningPlugin, provider). Close the returned handle on plugin disable. UiPage.token()/pageVersion() and UiPrompt.token() describe page/field identity; UiPage.actions() and opening parameters supply opaque action identifiers. Return interactions only through UiCallbacks.action(token), input(raw), and closed(); the bound callback validates and schedules them again. Registration does not check official DLC ownership. UiProvider.update(...) defaults to open(...). A native interface may update in place only if it replaces the page identity, every action token and all callbacks, including close handling. After a genuine vendor event changes client/resource readiness, update the provider’s own state and call api.changed(owningPlugin) for re-evaluation. Only enabled owners with a live registration may notify; the method itself is not proof that resources are ready. Optional UiProvider.refresh(player, page, theme) refreshes display data within the same page, such as a countdown, and defaults to false. The token, page version, action map and existing callbacks stay unchanged. Update display clones in the current open view only; never reopen an inventory or invoke an action. Return true after applying it, or false when unsupported or closed. Existing providers retain static snapshots until normal navigation or a player refresh; unsupported refreshes do not periodically reopen menus. Verify current page identity so a late result cannot overwrite a replacement page. An IA adapter can call the read-only api.itemsAdderUnavailable(player, page, theme) in the player’s scheduling context to reuse the host’s observed font registry, actual sent UUID/SHA-1 and matching successful load. Only null means the page resource is ready; other values describe a fallback reason. This check neither sends packs, changes preferences, evaluates official DLC rights nor grants trading authority. Its default returns IA_READINESS_UNSUPPORTED for existing service implementations and does not treat unknown state as readiness. Calling it requires a KiteMarket version shipping this method; do not bundle a replacement SDK into a provider. Public examples/ui/ contains the minimal white-frame configuration theme, and examples/ui-java/ contains a real Java IA adapter. The latter targets Java 21 with a compile-only public vendor API and the real TexturedInventoryWrapper. It registers example.itemsadder to render actual market pages and registered actions; it never invents balances or transaction outcomes. The public SDK remains Java 11. Do not install this example on Java 11 Legacy or unverified Folia nodes. The IA adapter fills the protected inventory returned by TexturedInventoryWrapper.getInternal(), registers the replacement holder, actions and callbacks, then calls the public showInventory(player) to display the font title. Opening only the internal inventory through Bukkit leaves IA’s placeholder title. Retain this order and whole-view protection so a previous close is handled separately from the new page. The KiteMarket-Examples-1.0.0.zip example bundle combines query and IA examples, including runnable JARs, themes, MIT resources, bilingual instructions and source/build files. Install the IA example JAR, place theme.yml in plugins/KiteMarket/themes/example-ia-java.yml, and copy itemsadder/ into plugins/ItemsAdder/contents/km_example/. Rebuild/send the pack using the installed IA instructions, register its identity and select /km ui itemsadder example-ia-java. Updates, stale closes, repeated clicks and chat input retain the shared safeguards. Source and resources identified as MIT in the configuration and Java examples may be modified for commercial interfaces without an additional KiteMC theme license. Other themes retain their own licenses. The examples’ real publishing pages have been opened on the representative environment; this record does not certify other packs or every page. Source, compilation and registration do not replace actual client verification.

Custom IA functional icons

Existing functional buttons may use your own registered IA items. resources.item-icons maps vanilla Material defaults; pages.<template>.slot-icons overrides physical slots on that template. Actual subject() trade items are never replaced:
UiItemIcons.resolve(page, theme) returns read-only bindings, creating no actions or readiness proof. Obtain and clone registered items through the real IA API, preserving host names, lore, quantities and actions. Missing icons report IA_RESOURCES_PENDING and fall back. Exact templates do not merge with '*'. Resources cannot substitute trade subjects, wallet amounts or transaction rules.

Pages, actions and lifecycle

UiPage.key() identifies the logical page; UiPage.template() selects theme configuration. Vanilla menus uses page IDs, while IA pages uses template IDs. The complete 35 pages and their main actions follow; “Same” means the template equals the page ID: Wizard templates follow the step: wizard-type, wizard-item, wizard-terms (buy order), wizard-sale-terms, wizard-auction-terms, then wizard-confirm. Default compact home source slots are 0 player head, 4 help, 8 claims, 20/22/24 trading categories, 45 wallet and 53 my orders. profile uses 20 interface preferences, 22 review queue, 24 history, 31 administration and 49 back; the administration entrance depends on permissions. The review list reuses history. Select home content with gui.home-layout: auto|compact|legacy; an existing menus.home preserves the legacy home under auto. See vanilla GUI customization for migration. Read current snapshots and actions instead of assuming all home layouts share one slot set. Quantity maxima use actual wallet funds, available inventory items and currency limits; auctions use only the main-hand stack. Transfers use real balances and any known backend receive capacity. Changed quotes require another choice, and final submission rechecks limits; a theme must not raise them independently. Receipts provide a separate “View / copy operation ID” action that sends the complete ID and copy control in chat. Summaries stay concise; inspect and the read-only API retain IDs. Sales support partial purchases at a per-item unit price. Their per-order minimum defaults to 1 and can be set from 1 to the listed quantity; a remainder below the minimum must be purchased together. Buy orders use unit prices for partial fulfillment, and auction starting prices apply to the whole lot. Render host amounts, input ranges and item descriptions. Remaining, total and traded quantities are separate, and real item properties remain intact. Display timestamps and countdowns do not replace database deadline checks. Claims use actual item stack limits, leaving assets in claims when inventory space is insufficient. The current page.actions() slot-to-opaque-token map is the action list. Entries without a token are informational. Never fabricate action strings or reuse a previous page’s tokens. Every open/update replaces identity, tokens and callbacks. Input returns through UiCallbacks.input(raw) and closure through closed(). Returning false from prompt() retains the host’s validated chat input and drafts. Registration can wait for database initialization. If lookup is null, listen for ServiceRegisterEvent; discard old registrations and views when replaced. Unregister on owner disable; the host handles safe fallback. Never manipulate player inventories from Folia’s global thread. The example does not claim Folia certification.

Troubleshooting

Installation and scope

After creating or obtaining a third-party theme, follow ItemsAdder integration to install its resources and register the actual pack identity. No official DLC product ID, signature or entitlement is needed. The plugin does not supply a commercial IA theme by default; unavailable themes retain the vanilla interface. The base plugin still follows network licensing for trading and asset exit. Compatibility records evidence for the base plugin, providers, and individual themes separately. Public SDKs and provider registration do not replace actual runtime acceptance.