Skip to content

Addon Development

XYAT edited this page Oct 7, 2026 · 3 revisions

English | 简体中文

Addon Development

KineticCore gives addon mods one API for GUI, F6 configuration, networking and compression, input and lifecycle events, hooks, command extensions, selectors, registry access and Minecraft helpers. Addons call only the public dev.xyat.kineticcore.api.*; internal/ is an implementation detail and may change at any time.

Depending on KineticCore

  1. Download the JAR that matches the addon's target version from Releases: kineticcore-<loader>-<minecraft>-<version>.jar.
  2. Add it to the build as a mod dependency (ModDevGradle Legacy modImplementation for Forge 1.20.1, implementation for NeoForge), and declare the kineticcore dependency in mods.toml / neoforge.mods.toml.
  3. Each Minecraft version of an addon uses the KineticCore JAR of the same version; never mix them.

Use a matching compiler toolchain and Java release target for each addon node: Java 17 for Forge 1.20.1, Java 21 for NeoForge 1.21.1, and Java 25 for NeoForge 26.1.2. KineticCore uses the same matrix; its Gradle daemon runs separately on Java 21.

The public API is documented in the source Javadoc. Running gradlew buildJavaDOC in the KineticCore repository writes javadoc/index.html and a shareable archive to the project root.

Which API to use

Controls are created on the KineticUi passed to build(KineticUi ui).

I need Use
A screen extends KineticPage + build(KineticUi ui); open it with KineticGui.open(page) or, from another page, openChild(page)
A container menu screen extends KineticContainerPage<M> + KineticClientMenus.register(...); the menu type comes from KineticMenuTypes
A button ui.button(x, y, w), .compact() for the narrow style; ui.itemButton(...) for an item icon button
An on/off switch ui.toggle(...)
Text input ui.textField(...), multi-line ui.textArea(...)
Number input (integer or decimal, min/max, negatives) ui.numberField(...)
Input with suggestions ui.autoComplete(...), for numbers ui.numberAutoComplete(...)
A choice ui.dropdown(...), ui.cycleButton(...) or ui.slider(...)
A colour ui.colorButton(...) / ui.colorSwatch(...); picker KineticSelectors.openColorPicker(...)
Tabs ui.tabBar(...) (fixed) or ui.tabStrip(...) (scrollable)
A list of text rows ui.selectionList(...)
Items as a list or a grid ui.itemSelectionList(...) / ui.itemGrid(...)
Rows with trailing buttons or toggles ui.actionList, ui.itemActionList, ui.multiActionList, ui.toggleList, ui.toggleActionList, ui.multiToggleList
Rows the page draws itself KineticRowList<T>, added with ui.add(...)
Rows of real controls that scroll together ui.scrollViewport(...)
A control the API does not have first check whether it is generic and belongs in the API; otherwise KineticCustomControl + ui.add(...)
Confirm dialog, right-click menu, tooltip page openDialog(...), openContextMenu(...) with KineticOverlays.MenuItem, builder .tooltip(...) or page showTooltip(...)
Pick an item, entity, NBT or colour KineticSelectors.open*
Let players move a HUD element KineticHudEditorPage
Draw on the HUD KineticClientEvents.onHudRender(...)
Draw icons or custom rows in an item tooltip KineticItemTooltips.registerComponentFactory(...) with a KineticTooltipComponent
Add a button to a vanilla or third-party screen KineticClientEvents.onScreenInitAfter(...)
Drawing, theme colours, text width KineticGraphics, KineticTheme, KineticText
Labels that follow world positions (name tags, damage numbers) KineticWorldRender.beginScreenOverlay(context) inside KineticClientEvents.onLevelRender(...)
Secondary (muted) text KineticTheme.muted(text); never the gray §7 / §8 codes
Input text cyan while unchanged, green once edited builder .defaultText(...) / .defaultValue(...), or .firstShownTextAsDefault() when the value is loaded after building
Player-visible text KineticI18n.translatable(...) with keys in zh_cn and en_us
An F6 config page KTConfigPage.builder(...) + KTConfigApi.register(...); server-owned values KTServerConfigSpec. If the client shows or uses server-managed values (tooltips, client effects), add .mirrorOnJoin() so each player loads them from the server on joining instead of using the local file; do not broadcast config edits to all players
Network packets PacketChannel (or KineticNetwork.channel(...)); compression KineticCompression
Commands KineticCommands (sub-commands under /kt); clickable help lines CommandText.suggest(...)
Clickable chat text CommandText.clickToRun / clickToSuggest / clickToCopy / clickToOpenUrl
Key bindings KineticKeyBindings; gestures such as double taps KineticInputGestures
Client and server events KineticClientEvents, KineticServerEvents, KineticWorldEvents, KineticLivingEvents
Client or server side, config folder KineticPlatform; config files KineticPaths
Registries and IDs KineticRegistries, KineticResourceIds; registration KineticItems, KineticMenuTypes, KineticEntityTypes
Flight permission KineticFlightSources
Player pose, crawling KineticPlayerPose, KineticCrawling
Force-loading chunks KineticChunkLoading
Shared injection points ClientHooks, CommonHooks, ServerHooks

Before adding API: first try a new parameter on an existing builder or interface, then a combination of existing controls. A new API type is only worth it for a new interaction that an unrelated addon could use unchanged.

Using Mixins

  • One mod should not have several Mixins for the same capability.
  • An injection that an unrelated addon could reuse as it is belongs in KineticCore's public API or hooks.
  • A Mixin that only serves one addon's own gameplay stays in that addon.
  • Do not reimplement GUI, input, config, networking or other capabilities the public API already provides.

Differences between versions

The API is the same on every version except where Minecraft itself changed.

From 1.21.1

  • Item text (KineticItemText) follows that version's /give syntax, see Item Text Syntax.
  • KineticClientAdvancements.all() returns List<AdvancementHolder>.
  • KineticEnchantments.register is not available: enchantments come from data pack JSON.
  • Networking uses NeoForge payloads; the KineticNetwork API is unchanged.

26.1.2

  • Key binding categories are ids: KineticKeyBindings.Builder.category(ResourceLocation). Categories outside the minecraft namespace are registered automatically; their name comes from the language key key.category.<namespace>.<path>.
  • Item model properties belong to model JSON: register them with KineticItemProperties.registerRange(id, codec) and registerConditional(id, codec), and refer to them from range_dispatch / condition models.
  • Villager trades are data-driven; KineticVillagerEvents is not available.
  • Spawn handlers reserve a place for first logins with ServerHooks.prepareFreshLogin(...); 26.1 creates the player object itself.

Build rule scripts

gradle/kinetic-addon-architecture.gradle from the KineticCore repository can be copied into an addon and applied with apply from, so that addon code going around the GUI API fails to compile. gradle/kinetic-addon-reobf-verification.gradle checks the reobfuscated JAR of 1.20.1 addons. The rules are explained in the GUI API Guide.

Clone this wiki locally