# website Full Documentation # Guides ## Configuration --- root: .components.layouts.MarkdownLayout title: Configuration nav-title: Configuration description: A guide for configuring the output of a generated Minecraft datapack. keywords: minecraft, datapack, kore, guide, configuration date-created: 2024-04-06 date-modified: 2024-01-08 routeOverride: /docs/guides/configuration position: 2 --- # DataPack Configuration The `configuration` function allows configuring the output of the generated datapack. ## Example ```kotlin dataPack("mypack") { configuration { prettyPrint = true prettyPrintIndent = " " } // ... rest of datapack code } ``` This will configure the JSON output to be pretty printed with two spaces for indentation. The available configuration options are: - `prettyPrint` - Whether to pretty print the JSON. Default is `false`. - `prettyPrintIndent` - The string to use for indenting when pretty printing. Only whitespace characters are allowed. Default is empty string. - `generatedFunctionsFolder` - The folder where the generated functions are stored. Defaults to `"generated_scopes"`. - `generateCommentOfGeneratedFunctionCall` - Whether to generate a comment when an implicit generated function is called. Default is `true`. Configuring a datapack is pretty useful for debugging. --- ## Creating A Datapack --- root: .components.layouts.MarkdownLayout title: Creating A Datapack nav-title: Creating A Datapack description: A guide for creating a Minecraft datapack using Kore. keywords: minecraft, datapack, kore, guide date-created: 2024-02-26 date-modified: 2024-01-08 routeOverride: /docs/guides/creating-a-datapack --- # Creating a DataPack A DataPack in Kore represents a Minecraft datapack that contains custom game data and resources. To create a DataPack, use the `dataPack` function: ```kotlin dataPack("my_datapack") { // datapack code here }.generate() ``` This will generate the datapack with the given name in the `out` folder by default. If `generate()` is not called, the datapack will not be generated. Check the [Generation](#generation) section for more information. ## Changing Output Folder To change the output folder, use the `path` property: ```kotlin dataPack("my_datapack") { path = Path("%appdata%/.minecraft/saves/my_world/datapacks") } ``` ## Adding Icon To add an icon to the datapack, use the `iconPath` property: ```kotlin dataPack("my_datapack") { iconPath = Path("icon.png") } ``` ## Configuration See [Configuration](./configuration) ## Pack Metadata The `dataPack` function generates a `pack.mcmeta` file containing metadata about the datapack. Configure this metadata using the `pack` block: ```kotlin dataPack("mydatapack") { pack { minFormat = packFormat(15) maxFormat = packFormat(20) description = textComponent("My Datapack") } } ``` - `minFormat` - The minimum supported pack format version. - `maxFormat` - The maximum supported pack format version. - `packFormat` - The explicit pack format version (optional). - `description` - A text component for the datapack description. - `supportedFormats` - The supported format versions (optional, automatically generated from range if needed). Kore automatically handles backward compatibility for older game versions. If your `minFormat` is below the threshold (82 for DataPacks, 65 for ResourcePacks), Kore will automatically include the legacy `pack_format` and `supported_formats` fields in the generated `pack.mcmeta` file to ensure compatibility with older versions of Minecraft. ### Targeting Minecraft 1.21.9+ Starting with Minecraft 1.21.9 (25w02a), the `pack_format` can be a decimal value to represent snapshots or minor versions. You can set this using `packFormat(Double)`: ```kotlin dataPack("my_1.21.9_datapack") { pack { minFormat = packFormat(94) maxFormat = packFormat(94) packFormat = packFormat(94.1) description = textComponent("Targeting 1.21.9") } } ``` Note that `minFormat` and `maxFormat` still only accept integer values (or full format `[major, minor]`). ## Filters Filters are used to filter out certain files from the datapack. For now, you can only filter out block files. For example, to filter out all `.txt` files: ```kotlin dataPack("my_datapack") { filter { blocks("stone*") } } ``` This will filter out all block files that start with `stone`. ## Content The main content of the datapack is generated from the various builder functions like `biome`, `lootTable`, etc. For example: ```kotlin dataPack("my_datapack") { // ... recipes { craftingShaped("enchanted_golden_apple") { pattern( "GGG", "GAG", "GGG" ) key("G", Items.GOLD_BLOCK) key("A", Items.APPLE) result(Items.ENCHANTED_GOLDEN_APPLE) } } } ``` This demonstrates adding a custom recipe to the datapack. ## Generation To generate the datapack, call the `generate()` function: ```kotlin dataPack("my_datapack") { // datapack code here }.generate() ``` This will generate the datapack with the given name in the `out` folder by default.
To change the output folder, use the `path` property: ```kotlin dataPack("my_datapack") { path = Path("%appdata%/.minecraft/saves/my_world/datapacks") }.generate() ``` ### Zip Generation To generate a zip file of the datapack, use the `generateZip` function: ```kotlin dataPack("my_datapack") { // datapack code here }.generateZip() ``` ### Jar Generation To generate a JAR file for your datapack, use the `generateJar` function. This function packages the datapack into a JAR file which can then be used directly with your Minecraft installation or distributed for others to use. ```kotlin dataPack("my_datapack") { // datapack code here }.generateJar() ``` By calling `generateJar()`, the generated JAR file will be placed in the default output folder. If you wish to specify a different location, use the `path` property: ```kotlin dataPack("my_datapack") { path = Path("path/to/output/folder") }.generateJar() ``` You can also configure the JAR generation for different mod loaders such as Fabric, Forge, Quilt, and NeoForge.
This will add metadata to the JAR file that is specific to the mod loader.
You will be able to include your datapack as a mod for your mod loader and simplify the installation process for users. Below are examples of how to set up these mod loaders: #### Fabric To configure Fabric mod loader, use the `fabric` block inside the `generateJar` function: ```kotlin dataPack("my_datapack") { // datapack code here }.generateJar { fabric { version = "1.2.5" contact { email = "kore@kore.kore" homepage = "https://kore.ayfri.com" } author("Ayfri") } } ``` This sets the Fabric version, and includes contact information and the author's name. #### Forge To configure Forge mod loader, use the `forge` block: ```kotlin dataPack("my_datapack") { // datapack code here }.generateJar { forge { mod { authors = "Ayfri" credits = "Generated by Kore" dependency("my_dependency") { mandatory = true version = "1.2.5" } } } } ``` This sets the mod authors, credits, and dependencies for Forge. #### Quilt To configure Quilt mod loader, use the `quilt` block: ```kotlin dataPack("my_datapack") { // datapack code here }.generateJar { quilt("kore") { metadata { contact { email = "kore@kore.kore" homepage = "https://kore.ayfri.com" } contributor("Ayfri", "Author") } version = "1.2.5" } } ``` This sets the metadata such as contact information and contributors for Quilt. #### NeoForge To configure NeoForge mod loader, use the `neoForge` block: ```kotlin dataPack("my_datapack") { // datapack code here }.generateJar { neoForge { mod { authors = "Ayfri" credits = "Generated by Kore" dependency("my_dependency") { type = NeoForgeDependencyType.REQUIRED version = "1.2.5" } } } } ``` This sets the authors, credits, and dependencies for NeoForge. ### Merging with existing datapacks To merge the generated datapack with an existing datapack, use the DSL with the function `mergeWithDatapacks`: ```kotlin dataPack("my_datapack") { // datapack code here }.generate { mergeWithDatapacks("existing_datapack 1", "existing_datapack 2") } ``` If a zip is provided, it will be considered as a datapack and merged with the generated datapack.
It will unzip the zip in a temporary folder of your system and merge it with the generated datapack, this will not remove the temporary folder. #### Checking for compatibility When merging with other datapacks, Kore will check if the pack format range overlaps. If it does not, it will print a warning message. Example: ```kotlin val myDatapack1 = dataPack("my_datapack 1") { // datapack code here pack { minFormat = packFormat(40) maxFormat = packFormat(40) } } val myDatapack2 = dataPack("my_datapack 2") { // datapack code here pack { minFormat = packFormat(50) maxFormat = packFormat(50) } } myDatapack1.generate { mergeWithDatapacks(myDatapack2) } ``` This will print out the following message: ``` The pack format range of the other pack is different from the current one. This may cause issues. Format range: current: 40..40 other: 50..50. ``` It also checks for `supportedFormats` and warns if the other pack is not supported. ## Publishing and Distribution Once you've generated your datapack, you may want to distribute it to the community. For automated publishing to platforms like Modrinth, CurseForge, and GitHub Releases, see the [GitHub Actions Publishing](./github-actions-publishing) guide. #### Tags When merging with other datapacks, Kore will merge the tags `minecraft/tags/function/load.json` and `minecraft/tags/functions/tick.json`. Example: ```kotlin val myDatapack1 = dataPack("my_datapack 1") { // datapack code here load("my_main_function") { say("Hello World!") } } val myDatapack2 = dataPack("my_datapack 2") { // datapack code here load("load") { say("Hello Everyone!") } } myDatapack1.generate { mergeWithDatapacks(myDatapack2) } ``` The resulting `load.json` file will contain: ```json { "replace": false, "values": [ "my_datapack_1:generated_scope/my_main_function", "my_datapack_2:generated_scope/load" ] } ``` --- # Commands ## Commands --- root: .components.layouts.MarkdownLayout title: Commands nav-title: Commands description: A comprehensive guide for using commands in Kore datapacks. keywords: minecraft, datapack, kore, guide, commands, execute, data, teleport date-created: 2026-02-03 date-modified: 2026-02-03 routeOverride: /docs/commands/commands --- # Commands Kore provides type-safe builders for all Minecraft commands. This page covers both simple and complex command usage with examples. Commands are used inside [Functions](./functions) to perform actions in the game. For dynamic command arguments, see [Macros](./macros). ## Simple Commands Simple commands are straightforward and take basic arguments like strings, numbers, or [selectors](#selectors). ### Say Command The `say` command broadcasts a message to all players in the chat. The message appears with the sender's name (the entity executing the command). For more advanced chat formatting, see [Chat Components](../concepts/chat_components). ```kotlin function("greetings") { say("Hello, world!") say("Welcome to the server!") } ``` Generated output: ```mcfunction say Hello, world! say Welcome to the server! ``` ### Teleport Command The `teleport` (or `tp`) command instantly moves entities to a new location. You can teleport to absolute coordinates, relative positions, or another entity's location. Optionally specify rotation (yaw/pitch) for the entity to face after teleporting. ```kotlin function("teleport_examples") { // Teleport to coordinates teleport(allPlayers(), 100.0, 64.0, 100.0) // Teleport to another entity teleport(allPlayers(), self()) // Teleport with rotation teleport(self(), vec3(0, 100, 0), rotation(0.rot, 90.rot)) } ``` Generated output: ```mcfunction tp @a 100 64 100 tp @a @s tp @s 0 100 0 0 90 ``` ### Give Command The `give` command adds items directly to a player's inventory. If the inventory is full, items drop on the ground. You can specify item count and use [Components](../concepts/components) for custom item data. ```kotlin function("give_items") { give(allPlayers(), Items.DIAMOND_SWORD) give(allPlayers(), Items.GOLDEN_APPLE, 64) } ``` Generated output: ```mcfunction give @a minecraft:diamond_sword give @a minecraft:golden_apple 64 ``` ### Kill Command The `kill` command instantly removes entities from the world. Killed entities trigger death events (drops, death messages for players). Use selectors to target specific entity types. ```kotlin function("cleanup") { kill(allEntities { type = EntityTypes.ZOMBIE }) kill(self()) } ``` Generated output: ```mcfunction kill @e[type=minecraft:zombie] kill @s ``` ### Effect Command The `effect` command applies or removes status effects (like Speed, Regeneration, Poison) from entities. Effects have duration (in seconds or infinite) and amplifier levels (0 = level I, 1 = level II, etc.). ```kotlin function("effects") { effect.give(allPlayers(), Effects.SPEED, 60, 1) effect.give(self(), Effects.REGENERATION, infinite = true) effect.clear(allPlayers()) effect.clear(self(), Effects.POISON) } ``` Generated output: ```mcfunction effect give @a minecraft:speed 60 1 effect give @s minecraft:regeneration infinite effect clear @a effect clear @s minecraft:poison ``` ### Gamemode Command The `gamemode` command changes a player's game mode (Survival, Creative, Adventure, Spectator). Each mode has different abilities and restrictions. ```kotlin function("modes") { gamemode(Gamemode.CREATIVE, allPlayers()) gamemode(Gamemode.SURVIVAL, player("Steve")) } ``` Generated output: ```mcfunction gamemode creative @a gamemode survival Steve ``` ### Time Command The `time` command controls the world's day/night cycle. Time is measured in ticks (20 ticks = 1 second, 24000 ticks = 1 Minecraft day). Day starts at 1000, noon at 6000, night at 13000. ```kotlin function("time_control") { time.set(TimeType.DAY) time.set(6000) time.add(1000) time.query(TimeQuery.DAYTIME) } ``` Generated output: ```mcfunction time set day time set 6000 time add 1000 time query daytime ``` ### Weather Command The `weather` command changes the world's weather state. Clear weather has full sunlight, rain reduces light and affects mob spawning, thunder enables lightning strikes and charged creeper creation. ```kotlin function("weather_control") { weather.clear() weather.rain(6000) weather.thunder() } ``` Generated output: ```mcfunction weather clear weather rain 6000 weather thunder ``` ### Summon Command The `summon` command spawns a new entity at the specified location. You can provide NBT data to customize the entity's properties (name, AI, equipment, etc.). ```kotlin function("spawn_mobs") { summon(EntityTypes.ZOMBIE, vec3(0, 64, 0)) summon(EntityTypes.CREEPER, vec3()) { this["CustomName"] = "\"Boom\"" this["NoAI"] = true } } ``` Generated output: ```mcfunction summon minecraft:zombie 0 64 0 summon minecraft:creeper ~ ~ ~ {CustomName:"\"Boom\"",NoAI:true} ``` ### SetBlock Command The `setblock` command places a single block at the specified coordinates. Use modes to control behavior: `destroy` (drops items), `keep` (only if air), or `replace` (default). ```kotlin function("build") { setBlock(vec3(0, 64, 0), Blocks.DIAMOND_BLOCK) setBlock(vec3(0, 65, 0), Blocks.STONE, SetBlockMode.REPLACE) } ``` Generated output: ```mcfunction setblock 0 64 0 minecraft:diamond_block setblock 0 65 0 minecraft:stone replace ``` ### Fill Command The `fill` command fills a rectangular region with blocks. Modes include: `replace` (all blocks), `hollow` (only outer shell), `outline` (shell without clearing inside), `keep` (only air blocks), and `destroy` (drops items). ```kotlin function("fill_area") { fill(vec3(0, 64, 0), vec3(10, 70, 10), Blocks.STONE) fill(vec3(0, 64, 0), vec3(10, 70, 10), Blocks.AIR, FillMode.REPLACE) fill(vec3(0, 64, 0), vec3(10, 70, 10), Blocks.GLASS, FillMode.HOLLOW) } ``` Generated output: ```mcfunction fill 0 64 0 10 70 10 minecraft:stone fill 0 64 0 10 70 10 minecraft:air replace fill 0 64 0 10 70 10 minecraft:glass hollow ``` ### Enchant Command The `enchant` command adds an enchantment to the item held by the target entity. The enchantment must be compatible with the item type. For more control over enchantments, see [Enchantments](../data-driven/enchantments). ```kotlin function("enchant_examples") { enchant(self(), Enchantments.MENDING) enchant(self(), Enchantments.SHARPNESS, 5) } ``` Generated output: ```mcfunction enchant @s minecraft:mending enchant @s minecraft:sharpness 5 ``` ### Difficulty Command The `difficulty` command gets or sets the world's difficulty level (Peaceful, Easy, Normal, Hard). Difficulty affects mob damage, hunger depletion, and whether hostile mobs spawn. ```kotlin function("difficulty_examples") { difficulty() // Query current difficulty difficulty(Difficulty.HARD) } ``` Generated output: ```mcfunction difficulty difficulty hard ``` ### SpawnPoint Command The `spawnpoint` command sets where a player respawns after death. Each player can have their own spawn point. Optionally specify the facing direction on respawn. ```kotlin function("spawnpoint_examples") { spawnPoint() // Set at current position spawnPoint(self()) spawnPoint(self(), vec3(100, 64, 100)) spawnPoint(self(), vec3(100, 64, 100), rotation(90, 0)) } ``` Generated output: ```mcfunction spawnpoint spawnpoint @s spawnpoint @s 100 64 100 spawnpoint @s 100 64 100 90 0 ``` ### SetWorldSpawn Command The `setworldspawn` command sets the default spawn point for all new players and players without a personal spawn point. This is where the world compass points to. ```kotlin function("worldspawn_examples") { setWorldSpawn() setWorldSpawn(vec3(0, 64, 0)) setWorldSpawn(vec3(0, 64, 0), rotation(0, 0)) } ``` Generated output: ```mcfunction setworldspawn setworldspawn 0 64 0 setworldspawn 0 64 0 0 0 ``` ### StopSound Command The `stopsound` command stops currently playing sounds for players. You can filter by sound source (master, music, weather, etc.) and specific sound. Useful for stopping looping sounds or music. ```kotlin function("stopsound_examples") { stopSound(self()) stopSound(self(), PlaySoundMixer.MASTER) stopSound(self(), PlaySoundMixer.MASTER, Sounds.Mob.Bat.TAKEOFF) stopSoundAllSources(self()) stopSoundAllSources(self(), Sounds.Mob.Bat.TAKEOFF) } ``` Generated output: ```mcfunction stopsound @s stopsound @s master stopsound @s master minecraft:mob/bat/takeoff stopsound @s * stopsound @s * minecraft:mob/bat/takeoff ``` ### Stopwatch Command The `stopwatch` command manages server-side timers that count game ticks. Stopwatches persist across sessions and can be queried in execute conditions. Useful for cooldowns, timed events, and measuring durations. ```kotlin function("stopwatch_examples") { val myStopwatch = stopwatch("my_timer") stopwatchCreate(myStopwatch) stopwatchQuery(myStopwatch) stopwatchRestart(myStopwatch) stopwatchRemove(myStopwatch) } ``` Generated output: ```mcfunction stopwatch my_datapack:my_timer create stopwatch my_datapack:my_timer query stopwatch my_datapack:my_timer restart stopwatch my_datapack:my_timer remove ``` You can also use stopwatches in execute conditions: ```kotlin function("stopwatch_condition") { execute { ifCondition { stopwatch(stopWatch("my_timer"), rangeOrInt(100)) } run { say("Timer reached 100 ticks!") } } } ``` Generated output: ```mcfunction execute if stopwatch my_datapack:my_timer 100 run say Timer reached 100 ticks! ``` ### Message Commands The `msg` command (aliases: `tell`, `w`) sends a private message to a specific player. The `teammsg` command (alias: `tm`) sends a message to all members of the sender's team. See [Scoreboards](../concepts/scoreboards) for team management. ```kotlin function("message_examples") { msg(self(), "Hello!") tell(self(), "Hello!") // Alias for msg w(self(), "Hello!") // Alias for msg teamMsg("Hello team!") tm("Hello team!") // Alias for teamMsg } ``` Generated output: ```mcfunction msg @s Hello! msg @s Hello! msg @s Hello! teammsg Hello team! teammsg Hello team! ``` ### Spectate Command The `spectate` command makes a player in Spectator mode view the game from another entity's perspective. Call without arguments to stop spectating. ```kotlin function("spectate_examples") { spectate() // Stop spectating spectate(self()) // Spectate target spectate(self(), self()) // Target and spectator } ``` Generated output: ```mcfunction spectate spectate @s spectate @s @s ``` ### Debug Commands These commands are server debugging utilities. `debug` starts/stops profiling and creates a report. `perf` captures performance metrics for 10 seconds. `jfr` starts/stops Java Flight Recorder profiling. ```kotlin function("debug_examples") { debugStart() debugStop() perfStart() perfStop() jfrStart() jfrStop() } ``` Generated output: ```mcfunction debug start debug stop perf start perf stop jfr start jfr stop ``` ## Complex Commands Complex commands have nested structures and multiple sub-commands. Kore provides specialized builders for these. ### Execute Command The `execute` command is one of the most powerful commands in Minecraft. It allows you to: - Change the execution context (who/where the command runs) - Add conditions (only run if criteria are met) - Store command results in scores or NBT - Chain multiple modifiers together Use `execute` with [Predicates](../data-driven/predicates) for complex conditions. #### Basic Execute ```kotlin function("execute_basic") { execute { asTarget(allPlayers()) run { say("Hello from execute!") } } } ``` Generated output: ```mcfunction execute as @a run say Hello from execute! ``` #### Execute with Conditions ```kotlin function("execute_conditions") { execute { asTarget(allEntities { limit = 3 sort = Sort.RANDOM }) ifCondition { score(self(), "points") greaterThanOrEqualTo 10 } run { say("You have enough points!") } } } ``` Generated output: ```mcfunction execute as @e[limit=3,sort=random] if score @s points >= 10 run say You have enough points! ``` #### Execute with Multiple Conditions ```kotlin function("execute_multi_conditions") { execute { ifCondition { score(self(), "a") matches rangeOrInt(0) score(self(), "b") matches rangeOrInt(1) score(self(), "c") matches rangeOrInt(2) } run { say("All conditions met!") } } } ``` Generated output: ```mcfunction execute if score @s a matches 0 if score @s b matches 1 if score @s c matches 2 run say All conditions met! ``` #### Execute with Position and Dimension ```kotlin function("execute_position") { execute { at(self()) positioned(vec3(0, 100, 0)) inDimension(Dimensions.THE_NETHER) run { setBlock(vec3(), Blocks.GLOWSTONE) } } } ``` Generated output: ```mcfunction execute at @s positioned 0 100 0 in minecraft:the_nether run setblock ~ ~ ~ minecraft:glowstone ``` #### Execute with Alignment and Anchoring ```kotlin function("execute_align") { execute { align(Axes.XYZ) anchored(Anchor.EYES) facing(vec3(0, 64, 0)) run { say("Aligned and facing!") } } } ``` Generated output: ```mcfunction execute align xyz anchored eyes facing 0 64 0 run say Aligned and facing! ``` #### Execute with Entity Relations ```kotlin function("execute_relations") { execute { asTarget(allEntities { type = EntityTypes.ZOMBIE }) on(Relation.ATTACKER) run { effect.give(self(), Effects.GLOWING, 10) } } } ``` Generated output: ```mcfunction execute as @e[type=minecraft:zombie] on attacker run effect give @s minecraft:glowing 10 ``` #### Execute Store Store command results in scores or NBT: ```kotlin function("execute_store") { execute { storeResult { score(self(), "my_score") } run { time.query(TimeQuery.DAYTIME) } } } ``` Generated output: ```mcfunction execute store result score @s my_score run time query daytime ``` ### Data Command The `data` command reads and writes NBT (Named Binary Tag) data on entities, block entities (chests, signs, etc.), and command storage. NBT stores complex data like inventory contents, entity attributes, and custom tags. Operations include `get` (read), `merge` (combine), `modify` (change specific paths), and `remove` (delete). #### Basic Data Operations ```kotlin function("data_basic") { data(self()) { get("Health") get("Inventory", 1.0) } } ``` Generated output: ```mcfunction data get entity @s Health data get entity @s Inventory 1 ``` #### Data Merge ```kotlin function("data_merge") { data(self()) { merge { this["CustomName"] = "\"Hero\"" this["Invulnerable"] = true } } } ``` Generated output: ```mcfunction data merge entity @s {CustomName:"\"Hero\"",Invulnerable:true} ``` #### Data Modify ```kotlin function("data_modify") { data(self()) { modify("Inventory") { append(Items.DIAMOND) } modify("Tags") { prepend("new_tag") } modify("Health") { set(20) } modify("Pos[0]") { set(self(), "Pos[0]") } } } ``` Generated output: ```mcfunction data modify entity @s Inventory append value "minecraft:diamond" data modify entity @s Tags prepend value "new_tag" data modify entity @s Health set value 20 data modify entity @s Pos[0] set from entity @s Pos[0] ``` #### Data Remove ```kotlin function("data_remove") { data(self()) { remove("CustomName") remove("Tags[0]") } } ``` Generated output: ```mcfunction data remove entity @s CustomName data remove entity @s Tags[0] ``` ### Scoreboard Command The `scoreboard` command manages objectives (score types) and player/entity scores. Scoreboards are essential for tracking game state, creating timers, and building game mechanics. See [Scoreboards](../concepts/scoreboards) for detailed usage. ```kotlin function("scoreboard_examples") { // Objectives scoreboard.objectives.add("kills", "playerKillCount", textComponent("Player Kills")) scoreboard.objectives.remove("old_objective") scoreboard.objectives.setDisplay(DisplaySlot.SIDEBAR, "kills") // Players scoreboard.players.set(allPlayers(), "kills", 0) scoreboard.players.add(self(), "kills", 1) scoreboard.players.remove(self(), "kills", 5) scoreboard.players.reset(self(), "kills") // Operations scoreboard.players.operation(self(), "total", Operation.ADD, self(), "kills") } ``` ### Bossbar Command The `bossbar` command creates and controls boss bars - the progress bars normally shown during boss fights. Boss bars can display custom text, colors, and progress values. They're useful for timers, progress indicators, and UI elements. ```kotlin function("bossbar_examples") { bossbar.add("my_bar", textComponent("My Boss Bar")) bossbar.set("my_bar") { color(BossBarColor.RED) max(100) value(50) visible(true) players(allPlayers()) style(BossBarStyle.NOTCHED_10) } bossbar.remove("my_bar") } ``` ### Team Command The `team` command creates and manages teams for players and entities. Teams control PvP (friendly fire), name tag visibility, collision, and chat colors. See [Scoreboards](../concepts/scoreboards) for more on teams. ```kotlin function("team_examples") { teams.add("red_team", textComponent("Red Team")) teams.modify("red_team") { color(Color.RED) friendlyFire(false) seeFriendlyInvisibles(true) } teams.join("red_team", allPlayers()) teams.leave(self()) } ``` ### Attribute Command The `attribute` command reads and modifies entity attributes like max health, movement speed, attack damage, and armor. You can get/set base values or add temporary modifiers that stack. ```kotlin function("attribute_examples") { attribute(self(), Attributes.GENERIC_MAX_HEALTH) { get() base.get() base.set(40.0) } attribute(self(), Attributes.GENERIC_MOVEMENT_SPEED) { modifiers.add("speed_boost", 0.1, AttributeModifierOperation.ADD_VALUE) modifiers.remove("speed_boost") } } ``` ### Schedule Command The `schedule` command delays function execution by a specified time. Useful for timers, cooldowns, and delayed effects. Time can be specified in ticks, seconds, or days. See [Scheduler Helper](../helpers/scheduler) for advanced scheduling patterns. ```kotlin function("schedule_examples") { val myFunction = function("delayed_action") { say("This runs later!") } schedule.function(myFunction, 100.ticks) schedule.function(myFunction, 5.seconds, ScheduleMode.REPLACE) schedule.clear(myFunction) } ``` ### Loot Command The `loot` command generates items from [Loot Tables](../data-driven/loot_tables) and distributes them to players, containers, or the world. Sources include fishing, killing entities, mining blocks, or direct loot table references. ```kotlin function("loot_examples") { // Give loot to a player loot(self()) { loot(LootTables.Gameplay.CAT_MORNING_GIFT) } // Fish loot with a tool loot(self()) { fish(LootTables.Gameplay.CAT_MORNING_GIFT, vec3(), Items.FISHING_ROD) } // Kill loot from an entity loot(self()) { kill(self()) } // Mine loot from a position loot(self()) { mine(vec3(), Items.DIAMOND_PICKAXE) } // Insert loot into a container loot { target { insert(vec3()) } source { kill(self()) } } // Replace block inventory slot loot { target { replaceBlock(vec3(), CONTAINER[0]) } source { loot(LootTables.Gameplay.CAT_MORNING_GIFT) } } // Replace entity equipment slot loot { target { replaceEntity(self(), ARMOR.HEAD) } source { loot(LootTables.Gameplay.CAT_MORNING_GIFT) } } // Inline loot table definition loot { target { give(self()) } source { loot { pool { rolls(1f) entries { item(Items.ANVIL) } } } } } } ``` Generated output: ```mcfunction loot give @s loot minecraft:gameplay/cat_morning_gift loot give @s fish minecraft:gameplay/cat_morning_gift ~ ~ ~ minecraft:fishing_rod loot give @s kill @s loot give @s mine ~ ~ ~ minecraft:diamond_pickaxe loot insert ~ ~ ~ kill @s loot replace block ~ ~ ~ container.0 loot minecraft:gameplay/cat_morning_gift loot replace entity @s armor.head loot minecraft:gameplay/cat_morning_gift loot give @s loot {pools:[{rolls:1.0f,entries:[{type:"minecraft:item",name:"minecraft:anvil"}]}]} ``` ### Particle Command The `particle` command spawns visual particle effects in the world. Particles have position, spread (delta), speed, and count. Use `force` mode to make particles visible from far away or through blocks. ```kotlin function("particle_examples") { // Simple particle particle(Particles.ASH) // Particle at position with delta and count particle(Particles.ASH, vec3(), vec3(), 1.0, 2) // Particle with force mode (visible from far away) particle(Particles.ASH, vec3(), vec3(), 1.0, 2, ParticleMode.FORCE) // Particle visible only to specific players particle(Particles.ASH, vec3(), vec3(), 1.0, 2, ParticleMode.NORMAL, allEntities()) } ``` Generated output: ```mcfunction particle minecraft:ash particle minecraft:ash ~ ~ ~ ~ ~ ~ 1 2 particle minecraft:ash ~ ~ ~ ~ ~ ~ 1 2 force particle minecraft:ash ~ ~ ~ ~ ~ ~ 1 2 normal @e ``` #### Special Particle Types ```kotlin function("special_particles") { particles { // Block particles with state block(Blocks.STONE_SLAB(states = mapOf("half" to "top"))) // Block crumble effect blockCrumble(Blocks.STONE) // Block marker (invisible barrier visualization) blockMarker(Blocks.STONE) // Falling dust fallingDust(Blocks.STONE) // Colored dust particles dust(Color.PURPLE, 2.0) dust(rgb(0xabcdef), 2.0) // Dust color transition dustColorTransition(Color.BLUE, 2.0, Color.RED) // Entity effect with color entityEffect(color = Color.GREEN) // Item particle with components item(Items.DIAMOND_SWORD { enchantments { enchantment(Enchantments.SHARPNESS, 5) } }) // Sculk charge with angle sculkCharge(PI / 2) // Shriek with delay shriek(100) // Trail particle trail(Color.RED, Triple(1, 2, 3), 10) // Vibration to position vibration(vec3(1, 2, 3), 10) } } ``` ### Clone Command The `clone` command copies blocks from one region to another. Supports cross-dimension cloning, filtering by block type, and different modes: `replace` (all blocks), `masked` (non-air only), `move` (removes source). Use `strict` to fail if regions overlap incorrectly. ```kotlin function("clone_examples") { // Basic clone clone { begin = vec3(0, 64, 0) end = vec3(10, 74, 10) destination = vec3(100, 64, 100) } // Clone between dimensions clone { begin = vec3(0, 64, 0) end = vec3(10, 74, 10) destination = vec3(0, 64, 0) from = Dimensions.THE_NETHER to = Dimensions.OVERWORLD } // Clone with mask mode clone { begin = vec3(0, 64, 0) end = vec3(10, 74, 10) destination = vec3(100, 64, 100) masked(CloneMode.MOVE) // Only non-air blocks, move instead of copy } // Clone with block filter clone { begin = vec3(0, 64, 0) end = vec3(10, 74, 10) destination = vec3(100, 64, 100) filter(Tags.Block.BASE_STONE_OVERWORLD, CloneMode.FORCE) } // Strict mode (fail if regions overlap incorrectly) clone { begin = vec3(0, 64, 0) end = vec3(10, 74, 10) destination = vec3(5, 64, 5) strict = true } } ``` Generated output: ```mcfunction clone 0 64 0 10 74 10 100 64 100 clone from minecraft:the_nether 0 64 0 10 74 10 to minecraft:overworld 0 64 0 clone 0 64 0 10 74 10 100 64 100 masked move clone 0 64 0 10 74 10 100 64 100 filtered #minecraft:base_stone_overworld force clone 0 64 0 10 74 10 5 64 5 strict ``` ## Selectors Selectors target entities in the world. Kore provides type-safe selector builders with filters for entity type, distance, scores, NBT, and more: ```kotlin function("selector_examples") { // All players say(allPlayers()) // Nearest player teleport(nearestPlayer(), vec3(0, 64, 0)) // Random player give(randomPlayer(), Items.DIAMOND) // All entities with filters kill(allEntities { type = EntityTypes.ZOMBIE limit = 10 sort = Sort.NEAREST distance = rangeOrIntEnd(10) }) // Entities with scores effect.give(allEntities { scores { score("kills") greaterThanOrEqualTo 5 } }, Effects.STRENGTH, 60) // Entities with NBT kill(allEntities { nbt = nbt { this["CustomName"] = "\"Target\"" } }) } ``` ## Macros Macros allow dynamic command arguments that are substituted at runtime. They're useful for creating reusable functions with parameters. ```kotlin function("greet_player") { say("Hello, ${macro("player_name")}!") } // Call with arguments load { function("greet_player", arguments = nbt { this["player_name"] = "Steve" }) } ``` Generated output: ```mcfunction $say Hello, $(player_name)! ``` For detailed macro usage including macro classes and validation, see [Macros](./macros). ## Raw Commands For commands not yet supported by Kore or for special cases, use `addLine`. This is also useful when working with [Macros](./macros) for fully dynamic commands: ```kotlin function("raw_commands") { addLine("say This is a raw command") addLine("execute as @a run say Hello") } ``` > Note: Using raw commands bypasses type safety. Prefer the DSL builders when available. ## Custom Commands Create your own command builders for mods or custom functionality. See [Functions](./functions) for more details on the Function context: ```kotlin fun Function.myModCommand(target: EntityArgument, value: Int) = addLine(command("mymod", literal(target.asString()), int(value))) // Usage function("custom") { myModCommand(self(), 42) } ``` Generated output: ```mcfunction mymod @s 42 ``` ## See Also - [Functions](./functions) - Create and organize command functions - [Macros](./macros) - Dynamic command arguments - [Predicates](../data-driven/predicates) - Conditions for execute if predicate - [Chat Components](../concepts/chat-components) - Formatted text in commands - [Tags](../data-driven/tags) - Use tags in commands and selectors ### External Resources - [Minecraft Wiki: Commands](https://minecraft.wiki/w/Commands) - Complete command reference - [Minecraft Wiki: Target selectors](https://minecraft.wiki/w/Target_selectors) - Selector syntax --- ## Functions --- root: .components.layouts.MarkdownLayout title: Functions nav-title: Functions description: A guide for creating functions in a datapack using Kore. keywords: minecraft, datapack, kore, guide, functions date-created: 2024-04-06 date-modified: 2026-02-03 routeOverride: /docs/commands/functions --- # Functions Functions represent reusable pieces of logic callable in a datapack. Create a function with the `function` builder: ```kotlin function("my_function") { say("Hello world!") } ``` Then in game, call the function with `/function my_datapack:my_function`. To call functions from other datapacks, see [Bindings](../advanced/bindings). The `function` builder returns a `FunctionArgument` object that you can reuse to call the function from other functions: ```kotlin val myFunction = function("my_function") { say("Hello world!") } function("my_second_function") { function(myFunction) } ``` ## Tags You can set the tag of the current function you're working in with the `setTag` function: ```kotlin function("my_function") { setTag(tagFile = "load", tagNamespace = "minecraft") } ``` This will add the function to the `minecraft:load` tag. But you have simpler builders for the most common tags: ```kotlin load { say("Hello world!") } tick { execute { ifCondition(myPredicate) run { say("Hello world!") } } } ``` - `load` tag: `minecraft:load` - `tick` tag: `minecraft:tick` This will create functions with randomly generated names, but you can also specify the name of the function: ```kotlin load("my_load_function") { say("Hello world!") } ``` # Commands Many common commands have convenience builders like `say`, `teleport`, etc. See the [Commands](./commands) page for a comprehensive guide with examples. For example: ```kotlin function("commands") { say("Hello!") // say command teleport(player("Steve"), 100.0, 64.0, 100.0) // tp command } ``` You can also build raw command strings and execute them: ```kotlin addLine("say Hello from raw command!") ``` > Note: This is not recommended, but can be useful for commands not yet supported by the DSL, or if you use [Macros](./macros). ## Available Commands All commands from the version cited in the [README](https://github.com/Ayfri/Kore/README.md) are available. For detailed documentation on each command, see [Commands](./commands). ## Custom Commands You can pretty easily add new commands by creating your own builders. For example, imagine you created a mod that adds a new command `/my_command` that takes a player name and a message as arguments. You can create a builder for this command like this: ```kotlin import io.github.ayfri.kore.functions.Function fun Function.myCommand(player: String, message: String) = addLine(command("my_command", literal(player), literal(message))) ``` Then you can use it like any other command: ```kotlin function("my_function") { myCommand("Steve", "Hello!") } ``` For commands that take complex types as arguments, you should use the `.asArg()` function inside `literal()` function. For Argument types, you don't have to use this. See the code of the repository for more examples.
[Link to `time` command.](https://github.com/Ayfri/Kore/blob/master/kore/src/main/kotlin/commands/Time.kt)
[Link to `weather` command.](https://github.com/Ayfri/Kore/blob/master/kore/src/main/kotlin/commands/Weather.kt) ## Complex Commands Some commands are more complex and require more than just a few arguments. For example, the `execute` or `data` commands. In that case, you can use complex builders that includes all the arguments of the command. But the syntax may vary depending on the command and you should definitely check the tests to see how to use them. An example of the `execute` command: ```kotlin execute { asTarget(allEntities { limit = 3 sort = Sort.RANDOM }) ifCondition { score(self(), "test") lessThan 10 predicate(myPredicate) } run { // be sure to import the run function, do not use the one from kotlin. teleport(entity) } } ``` You can use predicates in the `ifCondition` block to check complex conditions. See the [Predicates](../data-driven/predicates) documentation for more details. You may also have commands where you can create "contexts". An example of the `data` command: ```kotlin data(self()) { modify("Health", 20) modify("Inventory[0]", Items.DIAMOND_SWORD) } ``` # Macros See [Macros](./macros). # Generated Functions The same way the `load` and `tick` builders generate functions with random names, the `execute` builder also generates a function with a random name if you call multiple commands inside the `run` block. ```kotlin execute { run { say("Hello world!") say("Hello world2!") } } ``` This will generate a function with a random name that will be called by the `execute` command. > Note: The generated functions will be generated inside a folder named `generated_scopes` in the `functions` folder. > You can change the folder to whatever you want in [Configuration](./configuration). > Note: The generated name will have this pattern `generated_${hashCode()}`, where `hashCode()` is the hash code of the function. > This means that if you use the same `execute` builder multiple times, it will generate the same function name and reuse the same function. # Debugging You have multiple ways to debug your functions. First, a `debug` function is available, it is pretty much the same as `tellraw` but always displaying the message to everyone. ```kotlin function("my_function") { debug("Hello world!", Color.RED) } ``` You also have a `debug` block for printing a log message to the console for each command you call inside the block. ```kotlin function("my_function") { debug { say("hello !") } } ``` This will add a command call to `tellraw` command, writing the exact command generated, clicking on the text will also call the command. Example of what is generated: ```mcfunction say hello ! tellraw @a {"text":"/say hello !","click_event":{"action":"suggest_command","command":"say hello !"},"hoverEvent":{"action":"show_text","value":{"text":"Click to copy command","color":"gray","italic":true}}} ``` The last example is a function call to `startDebug()` (which is called by the `debug` block), this will add log messages to the start and the end of the function, plus a log message for each command called inside the function. ```mcfunction tellraw @a [{"text":"Running function ","color":"gray","italic":true},{"text":"my_datapack:my_function","color":"white","bold":true,"click_event":{"action":"run_command","command":"function my_datapack:my_function"},"hoverEvent":{"action":"show_text","value":{"text":"Click to execute function","color":"gray","italic":true}},"italic":true}] say hello ! tellraw @a {"text":"/say hello !","click_event":{"action":"suggest_command","command":"say hello !"},"hoverEvent":{"action":"show_text","value":{"text":"Click to copy command","color":"gray","italic":true}}} tellraw @a [{"text":"Finished running function ","color":"gray","italic":true},{"text":"my_datapack:my_function","color":"white","bold":true,"click_event":{"action":"run_command","command":"function my_datapack:my_function"},"hoverEvent":{"action":"show_text","value":{"text":"Click to execute function","color":"gray","italic":true}},"italic":true}] ``` You can call the command by clicking on the debug texts added. Also running `toString()` in a function will return the generated function as a string, so you can manipulate it as you want. ## See Also - [Commands](./commands) - Complete command reference - [Macros](./macros) - Dynamic command arguments - [Predicates](../data-driven/predicates) - Conditions in execute blocks - [Advancements](../data-driven/advancements) - Reward functions - [Tags](../data-driven/tags) - Function tags for load and tick events ### External Resources - [Minecraft Wiki: Function](https://minecraft.wiki/w/Function_(Java_Edition)) - Official function format --- ## Macros --- root: .components.layouts.MarkdownLayout title: Macros nav-title: Macros description: A guide for using macros in Minecraft functions. keywords: minecraft, datapack, kore, guide, macros, functions date-created: 2024-04-06 date-modified: 2026-02-03 routeOverride: /docs/commands/macros --- # Macros Macros allow dynamic command arguments that are substituted at runtime. Added in Minecraft 1.20.2, they enable creating reusable functions with parameters. For basic command usage, see [Commands](./commands). ## Using Macros To define a macro, use the `macro()` function: ```kotlin say("I'm gonna use the macro ${macro("foo")}") ``` Inside a Minecraft function: ```kotlin function("my_function") { say("This is my macro: ${macro("bar")}") } ``` When called, this will substitute the actual text of the macro. You can also evaluate a list of macros and have fully dynamic commands: ```kotlin eval("command", "arg1", "arg2") // equals to minecraft code: // $$(command) $(arg1) $(arg2) ``` ## Calling functions with macros You can call a function with macros by using the new `arguments` argument. ```kotlin function("my_function", arguments = nbt { this["bar"] = "baz" }) ``` That can also be a DataArgument (block position/entity selector/storage). ```kotlin function( "my_function", arguments = allEntities { type = EntityTypes.MARKER name = "test" }, path = "data.test" // optional path is available ) ``` ## Defining Macro Classes For more complex macro usage, you can create a `Macros` subclass to define your macros: ```kotlin class MyMacros : Macros() { val myMacro by "my_macro" } ``` Then pass an instance to your function: ```kotlin function("my_function", ::MyMacros) { say(macros.myMacro) } ``` Now you can access the macros on the `macros` property. This also allows validating macros that are required when calling the function with an NBT Compound. Exemple: ```kotlin class TeleportMacros : Macros() { val player by "player" } datapack { val teleportToSpawn = function("teleport_to_spawn", ::TeleportMacros) { teleport(player(macros.player), vec3()) } load { function(teleportToSpawn, arguments = nbt { this["name"] = "jeb_" }) // Will throw an error because function expects "player" macro function(teleportToSpawn, arguments = nbt { this["player"] = "jeb_" }) // Works fine } } ``` ## Best Practice When using macros, you can create a function with arguments that calls the function with the macros: ```kotlin fun main() { dataPack { function("teleport_to_spawn") { teleport(player(macro("player")), vec3()) } } } fun Function.teleportToSpawn(player: String) { function("teleport_to_spawn", arguments = nbt { this["player"] = player }) } ``` Then you can call this function with your argument as a macro: ```kotlin teleportToSpawn("jeb_") ``` ## Limitations - Macros can only be used in functions. - Macros aren't variables, they are just text substitutions, you can't do operations on them. - Macros are not type-checked. - It would be very difficult and long for Kore to allow macros as any argument of commands because of the wide variety of argument types and contexts in Minecraft commands. --- # Data driven ## Advancements --- root: .components.layouts.MarkdownLayout title: Advancements nav-title: Advancements description: A comprehensive guide for creating and managing advancements in Minecraft with Kore. keywords: minecraft, datapack, kore, guide, advancements, triggers, criteria, rewards date-created: 2024-01-08 date-modified: 2026-02-03 routeOverride: /docs/data-driven/advancements --- # Advancements Advancements are a system in Minecraft Java Edition that guides players through the game by setting goals and challenges to complete. They serve as in-game achievements that track player progress across various activities. ## Overview Advancements have several key characteristics: - **World-specific**: Progress is saved per world, not globally - **Game mode independent**: Can be completed in any game mode (Survival, Creative, Adventure, Spectator) - **Non-linear**: Can be completed in any order, regardless of parent-child relationships - **Notification system**: Completed advancements trigger toast notifications and chat messages - **Customizable**: Data packs can add custom advancements with unique criteria and rewards ## File Structure Advancements are stored as JSON files in data packs at: ``` data//advancement/.json ``` For complete JSON specification, see the [Minecraft Wiki - Advancement Definition](https://minecraft.wiki/w/Advancement_definition). ## Creating Advancements Use the `advancement` builder function to create advancements in Kore: ```kotlin dataPack("my_datapack") { advancement("my_first_advancement") { display(Items.DIAMOND, "My First Advancement", "Complete this challenge!") criteria { inventoryChanged("get_diamond", Items.DIAMOND) } } } ``` This generates `data/my_datapack/advancement/my_first_advancement.json`. ## Display Properties The display configuration controls how the advancement appears in the advancement screen and notifications. ### Basic Display ```kotlin advancement("example") { display(Items.DIAMOND_SWORD, "Title", "Description") { frame = AdvancementFrameType.TASK } } ``` ### Display with Chat Components For styled text with colors and formatting: ```kotlin advancement("styled_advancement") { display( icon = Items.GOLDEN_APPLE, title = textComponent("Golden Achievement") { color = Color.GOLD }, description = textComponent("Eat a golden apple") { color = Color.GRAY } ) { frame = AdvancementFrameType.GOAL } } ``` ### Display Properties Reference | Property | Type | Default | Description | |------------------|------------------------|----------|---------------------------------------------| | `icon` | `AdvancementIcon` | Required | Item displayed as the advancement icon | | `title` | `ChatComponents` | Required | Title shown in the advancement screen | | `description` | `ChatComponents` | Required | Description text below the title | | `frame` | `AdvancementFrameType` | `TASK` | Frame style: `TASK`, `GOAL`, or `CHALLENGE` | | `background` | `ModelArgument?` | `null` | Background texture (root advancements only) | | `showToast` | `Boolean?` | `true` | Show toast notification on completion | | `announceToChat` | `Boolean?` | `true` | Announce completion in chat | | `hidden` | `Boolean?` | `false` | Hide until completed (and hide children) | ### Frame Types Each frame type produces different visual feedback: | Frame | Notification Header | Header Color | Sound | |-------------|-----------------------|--------------|---------------| | `TASK` | "Advancement Made!" | Yellow | Standard | | `GOAL` | "Goal Reached!" | Yellow | Standard | | `CHALLENGE` | "Challenge Complete!" | Pink | Special music | > **Note:** Root advancements (without a parent) don't trigger notifications or chat messages. ### Icon with Components Customize the icon with item components like enchantments: ```kotlin advancement("enchanted_icon") { display(Items.DIAMOND_SWORD, "Master Swordsman", "Wield a legendary blade") { icon(Items.DIAMOND_SWORD, count = 1) { enchantments { enchantment(Enchantments.SHARPNESS, 5) enchantment(Enchantments.UNBREAKING, 3) } customName(textComponent("Legendary Sword", Color.GOLD)) } frame = AdvancementFrameType.CHALLENGE } } ``` ### Hidden Advancements Hidden advancements remain invisible (along with their children) until completed: ```kotlin advancement("secret_discovery") { display(Items.ENDER_EYE, "???", "A mysterious discovery") { hidden = true frame = AdvancementFrameType.CHALLENGE } // ...criteria } ``` ## Parent Advancements Set a parent to position the advancement in an existing tree: ```kotlin advancement("child_advancement") { // Reference vanilla advancement parent = Advancements.Story.ROOT display(Items.IRON_PICKAXE, "Mining Progress", "Continue your journey") // ... } ``` Or reference a custom advancement: ```kotlin advancement("child_advancement") { parent = AdvancementArgument("my_root", "my_namespace") // ... } ``` ### Creating a New Tab To create a new advancement tab, create a root advancement (no parent) with display and a background: ```kotlin advancement("my_custom_tab") { display(Items.COMPASS, "Custom Adventures", "Begin your journey") { frame = AdvancementFrameType.TASK background = Textures.Gui.Advancements.Backgrounds.STONE } criteria { tick("auto_grant") // Grants immediately } } ``` ## Criteria Criteria define the conditions that must be met to complete the advancement. Each criterion has a **trigger ** that activates when specific game events occur. ### Basic Criteria ```kotlin advancement("eat_apple") { criteria { consumeItem("eat_golden_apple") { item { items = listOf(Items.GOLDEN_APPLE) } } } } ``` ### Multiple Criteria Add multiple criteria to an advancement: ```kotlin advancement("multi_criteria") { criteria { inventoryChanged("get_diamond", Items.DIAMOND) inventoryChanged("get_emerald", Items.EMERALD) enterBlock("enter_water") { block = Blocks.WATER } } } ``` ### Criteria with Predicate Conditions Add predicate conditions to criteria for additional checks: ```kotlin advancement("conditional_criteria") { criteria { consumeItem("eat_apple_lucky") { item { items = listOf(Items.GOLDEN_APPLE) } conditions { randomChance(0.5f) // 50% chance timeCheck(6000f..18000f) // Daytime only } } } } ``` For a complete guide on predicates, see the [Predicates](./predicates) documentation. ## Triggers Triggers are the events that activate criteria. Kore supports all vanilla triggers: | Trigger | Description | |--------------------------------|-------------------------------------------| | `allayDropItemOnBlock` | Allay drops an item on a block | | `anyBlockUse` | Player uses any block | | `avoidVibration` | Player avoids a vibration while sneaking | | `beeNestDestroyed` | Player breaks a bee nest/beehive | | `bredAnimals` | Player breeds two animals | | `brewedPotion` | Player takes item from brewing stand | | `changedDimension` | Player travels between dimensions | | `channeledLightning` | Player uses Channeling enchantment | | `constructBeacon` | Beacon structure is updated | | `consumeItem` | Player consumes an item | | `crafterRecipeCrafted` | Crafter crafts a recipe | | `curedZombieVillager` | Player cures a zombie villager | | `defaultBlockUse` | Player uses a block (default interaction) | | `effectsChanged` | Player's effects change | | `enchantedItem` | Player enchants an item | | `enterBlock` | Player enters a block | | `entityHurtPlayer` | Entity hurts the player | | `entityKilledPlayer` | Entity kills the player | | `fallAfterExplosion` | Player falls after an explosion | | `fallFromHeight` | Player falls from a height | | `filledBucket` | Player fills a bucket | | `fishingRodHooked` | Player hooks something with fishing rod | | `heroOfTheVillage` | Player becomes Hero of the Village | | `impossible` | Never triggers (manual grant only) | | `inventoryChanged` | Player's inventory changes | | `itemDurabilityChanged` | Item durability changes | | `itemUsedOnBlock` | Player uses item on a block | | `killedByArrow` | Player kills entities with arrows | | `killMobNearSculkCatalyst` | Kill a mob near sculk catalyst | | `levitation` | Player has Levitation effect | | `lightningStrike` | Lightning strikes near player | | `location` | Player is at a specific location | | `netherTravel` | Player travels via Nether | | `placedBlock` | Player places a block | | `playerGeneratesContainerLoot` | Player generates container loot | | `playerHurtEntity` | Player hurts an entity | | `playerInteractedWithEntity` | Player interacts with entity | | `playerKilledEntity` | Player kills an entity | | `playerShearedEquipment` | Player shears equipment from entity | | `recipeCrafted` | Player crafts a recipe | | `recipeUnlocked` | Player unlocks a recipe | | `rideEntityInLava` | Player rides entity in lava | | `shotCrossbow` | Player shoots a crossbow | | `sleptInBed` | Player sleeps in bed | | `slideDownBlock` | Player slides down a block | | `startedRiding` | Player starts riding | | `summonedEntity` | Player summons an entity | | `tameAnimal` | Player tames an animal | | `targetHit` | Player hits a target block | | `thrownItemPickedUpByEntity` | Entity picks up thrown item | | `thrownItemPickedUpByPlayer` | Player picks up thrown item | | `tick` | Every game tick (use for auto-grant) | | `usedEnderEye` | Player uses Eye of Ender | | `usedTotem` | Player uses Totem of Undying | | `usingItem` | Player is using an item | | `villagerTrade` | Player trades with villager | | `voluntaryExile` | Player gets Bad Omen | For detailed trigger documentation, see the [Triggers](./advancements/triggers) page. ### Trigger Examples ```kotlin advancement("trigger_examples") { criteria { // Dimension travel changedDimension("enter_nether") { from = Dimensions.OVERWORLD to = Dimensions.THE_NETHER } // Block interaction enterBlock("step_on_pressure_plate") { block = Blocks.STONE_PRESSURE_PLATE } // Entity interaction playerKilledEntity("kill_zombie") { entity { type(EntityTypes.ZOMBIE) } } // Effect-based effectsChanged("get_speed") { effect(Effects.SPEED) { amplifier = rangeOrInt(1..3) duration = rangeOrInt(100..200) } } // Never triggers - for manual grant via commands impossible("manual_only") } } ``` ## Requirements Requirements define how criteria combine to complete the advancement. By default, **all criteria must be completed** (AND logic). ### Simple Requirements Require specific criteria by name: ```kotlin advancement("single_requirement") { criteria { inventoryChanged("get_diamond", Items.DIAMOND) inventoryChanged("get_emerald", Items.EMERALD) } // Only diamond is required (emerald is optional) requirements("get_diamond") } ``` ### AND Logic (All Required) Require multiple criteria (all must be met): ```kotlin advancement("and_requirements") { criteria { inventoryChanged("get_diamond", Items.DIAMOND) inventoryChanged("get_emerald", Items.EMERALD) } // Both required requirements("get_diamond", "get_emerald") } ``` ### OR Logic (Any Required) Use nested lists for OR groups: ```kotlin advancement("or_requirements") { criteria { inventoryChanged("get_diamond", Items.DIAMOND) inventoryChanged("get_emerald", Items.EMERALD) inventoryChanged("get_gold", Items.GOLD_INGOT) } // Need diamond OR emerald, AND gold requirements( listOf("get_diamond", "get_emerald"), // Either diamond or emerald listOf("get_gold") // AND gold ) } ``` ## Rewards Define rewards granted when the advancement is completed: ```kotlin advancement("rewarding_advancement") { // ...display and criteria rewards { experience = 100 loots(LootTables.Chests.IGLOO_CHEST) recipes(Recipes.DIAMOND_SWORD) } } ``` ### Reward Properties | Property | Type | Description | |--------------|----------------------------|-----------------------------------| | `experience` | `Int?` | Experience points awarded | | `function` | `FunctionArgument?` | Function to execute on completion | | `loot` | `List?` | Loot tables to roll | | `recipes` | `List?` | Recipes to unlock | ### Function Rewards Execute commands when the advancement is completed: ```kotlin // Anonymous generated function rewards { function { say("Congratulations!") } } // Named function rewards { function("celebration") { say("You did it!") playsound(Sounds.UI_TOAST_CHALLENGE_COMPLETE, PlaySoundMixer.MASTER, self()) } } // Reference existing function rewards { function = myExistingFunction } ``` ### Multiple Rewards ```kotlin advancement("full_rewards") { rewards { experience = 500 function("reward_function") { give(self(), Items.DIAMOND, 10) effect(self(), Effects.REGENERATION, 200, 2) } loots( LootTables.Chests.END_CITY_TREASURE, LootTables.Chests.STRONGHOLD_CORRIDOR ) recipes( Recipes.DIAMOND_PICKAXE, Recipes.DIAMOND_SWORD ) } } ``` ## Telemetry Control whether completing this advancement sends telemetry data: ```kotlin advancement("tracked_advancement") { sendsTelemetryEvent = true // Default is false } ``` ## Managing Advancements with Commands Use the `/advancement` command to grant, revoke, or test advancements. ### Using the Advancement Command Block ```kotlin function("manage_advancements") { advancement { // Grant/revoke everything grantEverything(self()) revokeEverything(self()) // Specific advancement grant(self(), Advancements.Adventure.KILL_A_MOB) revoke(self(), Advancements.Adventure.KILL_A_MOB) // With route and criterion grant(self(), AdvancementRoute.ONLY, Advancements.Story.ROOT, "criterion_name") } } ``` ### Target-Specific Block ```kotlin function("player_advancements") { advancement(self()) { grantEverything() grant(Advancements.Story.IRON_TOOLS) revoke(AdvancementRoute.FROM, Advancements.Nether.ROOT) } } ``` ### Advancement Routes | Route | Description | |-----------|--------------------------------------------| | `ONLY` | Only the specified advancement | | `FROM` | Advancement and all its children | | `THROUGH` | Advancement, all parents, and all children | | `UNTIL` | Advancement and all its parents | ## Complete Example Here's a comprehensive example demonstrating multiple features: ```kotlin dataPack("adventure_pack") { // Create a custom tab val customRoot = advancement("custom/root") { display(Items.COMPASS, "Custom Adventures", "Begin your custom journey") { frame = AdvancementFrameType.TASK background = Textures.Gui.Advancements.Backgrounds.ADVENTURE } criteria { tick("start") } } // Child advancement with multiple criteria advancement("custom/explorer") { parent = customRoot display(Items.MAP, "Explorer", "Visit multiple biomes") { frame = AdvancementFrameType.GOAL showToast = true announceToChat = true } criteria { location("visit_forest") { location { biome = Biomes.FOREST } } location("visit_desert") { location { biome = Biomes.DESERT } } location("visit_ocean") { location { biome = Biomes.OCEAN } } } // Any two biomes complete the advancement requirements( listOf("visit_forest", "visit_desert"), listOf("visit_forest", "visit_ocean"), listOf("visit_desert", "visit_ocean") ) rewards { experience = 50 } } // Challenge advancement advancement("custom/master") { parent = customRoot display(Items.NETHERITE_SWORD, "Master Adventurer", "Complete the ultimate challenge") { icon(Items.NETHERITE_SWORD) { enchantments { enchantment(Enchantments.SHARPNESS, 5) } } frame = AdvancementFrameType.CHALLENGE hidden = true } criteria { playerKilledEntity("kill_dragon") { entity { type(EntityTypes.ENDER_DRAGON) } } playerKilledEntity("kill_wither") { entity { type(EntityTypes.WITHER) } } } rewards { experience = 1000 function("master_reward") { title(self(), textComponent("MASTER ADVENTURER", Color.GOLD), textComponent("")) } } } } ``` ## Best Practices ### 1. Logical Progression Structure advancements to guide players naturally, even though completion order is flexible. ### 2. Meaningful Rewards Match reward value to advancement difficulty - challenging advancements should have worthwhile rewards. ### 3. Clear Descriptions Write descriptions that clearly explain what players need to do. ### 4. Use Hidden Sparingly Reserve hidden advancements for genuine surprises or easter eggs. ### 5. Test Criteria Verify criteria trigger correctly in-game before releasing your data pack. ## See Also - [Triggers](./advancements/triggers) - Complete trigger reference - [Predicates](./predicates) - Conditions for advancement criteria - [Loot Tables](./loot-tables) - Loot rewards - [Functions](../commands/functions) - Function rewards - [Tags](./tags) - Use tags in conditions ## External Resources - [Minecraft Wiki: Advancement](https://minecraft.wiki/w/Advancement) - Game mechanics overview - [Minecraft Wiki: Advancement Definition](https://minecraft.wiki/w/Advancement_definition) - JSON format specification --- ## Advancements Triggers --- root: .components.layouts.MarkdownLayout title: Advancements Triggers nav-title: Advancements Triggers description: A guide for using advancements triggers in Minecraft with Kore. keywords: minecraft, datapack, kore, guide, advancements, triggers date-created: 2024-08-01 date-modified: 2024-08-01 routeOverride: /docs/data-driven/advancements/triggers --- ## Available Triggers Below is the comprehensive list of available trigger types. Each trigger includes a description, its properties with explanations, and an example usage in Kotlin. --- ### `allayDropItemOnBlock` **Description:** Triggers when an allay drops an item on a block. **Properties:** - `location`: The location where the item is dropped. **Example:** ```kotlin allayDropItemOnBlock("allay_drop") { location { block { blocks(Blocks.GRASS_BLOCK, Blocks.DIRT) } } } ``` --- ### `anyBlockUse` **Description:** Triggers when a player uses any block. **Properties:** _None._ **Example:** ```kotlin anyBlockUse("use_block") { conditions { playerProperties { lookingAt(Blocks.CRAFTING_TABLE) } } } ``` --- ### `avoidVibrations` **Description:** Triggers when a player avoids vibrations. **Properties:** - `location`: The location where vibrations are avoided. **Example:** ```kotlin avoidVibrations("avoid_sculk") { conditions { location { block = Blocks.SCULK_SENSOR } } } ``` --- ### `beeNestDestroyed` **Description:** Triggers when a bee nest is destroyed. **Properties:** - `block`: The type of block that was destroyed. - `item`: The item involved in the destruction. - `numBeesInside`: The number of bees that were inside the nest. **Example:** ```kotlin beeNestDestroyed("destroy_nest") { block = Blocks.BEE_NEST numBeesInside = rangeOrInt(1) item { item(Items.HONEYCOMB) } } ``` --- ### `bredAnimals` **Description:** Triggers when animals are bred. **Properties:** - `child`: The child animal resulting from the breeding. - `parent`: One of the parent animals. - `partner`: The other parent animal. **Example:** ```kotlin bredAnimals("breed_animals") { child { conditions { entityProperties { type(EntityTypes.COW) } } } parent { conditions { entityProperties { type(EntityTypes.COW) } } } partner { conditions { entityProperties { type(EntityTypes.COW) } } } } ``` --- ### `changedDimension` **Description:** Triggers when a player changes dimension. **Properties:** - `from`: The original dimension. - `to`: The new dimension. **Example:** ```kotlin changedDimension("enter_nether") { from = Dimensions.OVERWORLD to = Dimensions.NETHER } ``` --- ### `channeledLightning` **Description:** Triggers when lightning is channeled. **Properties:** - `victims`: A list of entities affected by the lightning. **Example:** ```kotlin channeledLightning("lightning_rod") { victim { conditions { entityProperties { type(EntityTypes.CREEPER) } } } } ``` --- ### `constructBeacon` **Description:** Triggers when a beacon is constructed. **Properties:** - `level`: The level of the beacon. **Example:** ```kotlin constructBeacon("make_beacon") { level = rangeOrInt(4) } ``` --- ### `consumeItem` **Description:** Triggers when an item is consumed. **Properties:** - `item`: The item that was consumed. **Example:** ```kotlin consumeItem("eat_apple") { item { items = listOf(Items.GOLDEN_APPLE) } } ``` --- ### `crafterRecipeCrafted` **Description:** Triggers when a recipe is crafted. **Properties:** - `recipeId`: The ID of the crafted recipe. - `ingredients`: The ingredients used in the recipe. **Example:** ```kotlin crafterRecipeCrafted("craft_diamond") { recipeId = Recipes.DIAMOND ingredient(Items.DIAMOND) { components { damage(0) } } } ``` --- ### `curedZombieVillager` **Description:** Triggers when a zombie villager is cured. **Properties:** - `villager`: The villager involved in the curing. - `zombie`: The zombie involved in the curing. **Example:** ```kotlin curedZombieVillager("cure_zombie") { villager { conditions { entityProperties { type(EntityTypes.VILLAGER) } } } zombie { conditions { entityProperties { type(EntityTypes.ZOMBIE) } } } } ``` --- ### `defaultBlockUse` **Description:** Triggers when a block is used with default interaction. **Properties:** _None._ **Example:** ```kotlin defaultBlockUse("use_default") { conditions { playerProperties { lookingAt(Blocks.CHEST) } } } ``` --- ### `effectsChanged` **Description:** Triggers when a player's effects change. **Properties:** - `effects`: The effects that have changed. - `source`: The source of the effect changes. **Example:** ```kotlin effectsChanged("get_effect") { effect(Effects.SPEED) { amplifier = rangeOrInt(1..3) duration = rangeOrInt(100..200) } source { conditions { entityProperties { type(EntityTypes.WITCH) } } } } ``` --- ### `enchantedItem` **Description:** Triggers when an item is enchanted. **Properties:** - `item`: The item that was enchanted. - `levels`: The levels of enchantment applied. **Example:** ```kotlin enchantedItem("enchant_item") { item { item(Items.DIAMOND_SWORD) } levels = rangeOrInt(1..3) } ``` --- ### `enterBlock` **Description:** Triggers when a player enters a specific block. **Properties:** - `block`: The block being entered. - `states`: The state properties of the block. **Example:** ```kotlin enterBlock("enter_block") { block = Blocks.REDSTONE_LAMP states { this["lit"] = "true" } } ``` --- ### `entityHurtPlayer` **Description:** Triggers when an entity hurts a player. **Properties:** - `damage`: Details about the damage inflicted. **Example:** ```kotlin entityHurtPlayer("hurt_player") { damage { sourceEntity { type(EntityTypes.ZOMBIE) } taken = rangeOrDouble(5.0..10.0) type { tag(Tags.DamageType.IS_FALL) } } } ``` --- ### `entityKilledPlayer` **Description:** Triggers when an entity kills a player. **Properties:** - `entity`: The entity that killed the player. - `killingBlow`: Details about the killing blow. **Example:** _Not provided in the original examples._ --- ### `fallAfterExplosion` **Description:** Triggers after falling from an explosion. **Properties:** - `startPosition`: The starting position of the fall. - `distance`: The distance fallen. - `cause`: The cause of the fall. **Example:** ```kotlin fallAfterExplosion("tnt_launch") { startPosition { position { y = rangeOrInt(100..200) } } distance { horizontal(10f) } } ``` --- ### `fallFromHeight` **Description:** Triggers when falling from a height. **Properties:** - `startPosition`: The starting position of the fall. - `distance`: The distance fallen. **Example:** ```kotlin fallFromHeight("high_fall") { distance { vertical(20f) } } ``` --- ### `filledBucket` **Description:** Triggers when a bucket is filled. **Properties:** - `item`: The bucket item that was filled. **Example:** ```kotlin filledBucket("fill_bucket") { item { item(Items.WATER_BUCKET) } } ``` --- ### `fishingRodHooked` **Description:** Triggers when a fishing rod hooks something. **Properties:** - `entity`: The entity hooked by the fishing rod. - `item`: The item used as the fishing rod. - `rod`: Details about the fishing rod. **Example:** ```kotlin fishingRodHooked("catch_fish") { item { item(Items.FISHING_ROD) } rod { components { enchantments { enchantment(Enchantments.LUCK_OF_THE_SEA, 3) } } } } ``` --- ### `heroOfTheVillage` **Description:** Triggers when becoming a hero of the village. **Properties:** _None._ **Example:** ```kotlin heroOfTheVillage("save_village") { conditions { location { dimension = Dimensions.OVERWORLD } } } ``` --- ### `impossible` **Description:** Prevents the advancement from being achieved. Useful for creating advancements that should only trigger functions. **Properties:** _None._ **Example:** ```kotlin impossible("impossible") ``` --- ### `inventoryChanged` **Description:** Triggers when inventory contents change. **Properties:** - `items`: The items involved in the inventory change. - `slots`: The inventory slots affected. **Example:** ```kotlin inventoryChanged("get_diamond") { item { item(Items.DIAMOND) } slots { empty = rangeOrInt(1..3) } } ``` --- ### `itemDurabilityChanged` **Description:** Triggers when item durability changes. **Properties:** - `delta`: The change in durability. - `durability`: The current durability of the item. - `item`: The item whose durability changed. **Example:** ```kotlin itemDurabilityChanged("tool_break") { delta = rangeOrInt(-10..-1) item { item(Items.DIAMOND_PICKAXE) } } ``` --- ### `itemUsedOnBlock` **Description:** Triggers when an item is used on a block. **Properties:** - `location`: The location where the item was used. **Example:** ```kotlin itemUsedOnBlock("bone_meal_use") { location { predicate { locationCheck { block { blocks(Blocks.GRASS_BLOCK, Blocks.DIRT) } } } } } ``` --- ### `killedByArrow` **Description:** Triggers when killed by a crossbow. **Properties:** - `firedFromWeapon`: The weapon used to fire the arrow. - `uniqueEntityTypes`: The number of unique entity types involved. - `victims`: The entities that were killed. **Example:** ```kotlin killedByArrow("killed_by_arrow") { firedFromWeapon { items = listOf(Items.BOW) components { enchantments { enchantment(Enchantments.POWER, 5) } } } uniqueEntityTypes = rangeOrInt(1..5) victim { conditions { entityProperties { type(EntityTypes.PLAYER) } } } } ``` --- ### `killMobNearSculkCatalyst` **Description:** Triggers when a mob is killed near a sculk catalyst. **Properties:** - `entity`: The entity that was killed. - `killingBlow`: Details about the killing blow. **Example:** ```kotlin killMobNearSculkCatalyst("kill_mob") { entity { type(EntityTypes.ZOMBIE) } killingBlow { sourceEntity { type(EntityTypes.PLAYER) } } } ``` --- ### `levitation` **Description:** Triggers during levitation. **Properties:** - `distance`: The distance of levitation. - `duration`: The duration of levitation. **Example:** ```kotlin levitation("float_up") { distance { y(10f) } duration = rangeOrInt(10..20) } ``` --- ### `lightningStrike` **Description:** Triggers on a lightning strike. **Properties:** - `bystander`: The bystanders affected by the lightning. - `lightning`: Details about the lightning strike. **Example:** ```kotlin lightningStrike("struck") { bystander { type { conditions { entityProperties { type(EntityTypes.CREEPER) } } } } } ``` --- ### `location` **Description:** Triggers every second based on location conditions. **Properties:** - `location`: The specific location conditions for the trigger. **Example:** ```kotlin location("reach_end") { conditions { location { dimension = Dimensions.THE_END } } } ``` --- ### `netherTravel` **Description:** Triggers when a player enters or exits the Nether. **Properties:** - `distance`: The distance traveled during the dimension change. - `startPosition`: The starting position before the change. **Example:** ```kotlin netherTravel("enter_nether") { distance { horizontal(100f) } startPosition { position { x = rangeOrInt(0..100) z = rangeOrInt(0..100) } } } ``` --- ### `placedBlock` **Description:** Triggers when a block is placed. **Properties:** - `location`: The location where the block was placed. **Example:** ```kotlin placedBlock("place_block") { conditions { location { biomes(Biomes.PLAINS) } } } ``` --- ### `playerGeneratesContainerLoot` **Description:** Triggers when container loot is generated. **Properties:** - `lootTable`: The loot table used to generate the container loot. **Example:** ```kotlin playerGeneratesContainerLoot("find_treasure", LootTables.Chests.BURIED_TREASURE) ``` --- ### `playerHurtEntity` **Description:** Triggers when a player hurts an entity. **Properties:** - `damage`: Details about the damage inflicted. - `entity`: The entity that was hurt. **Example:** ```kotlin playerHurtEntity("hurt_mob") { damage { taken = rangeOrDouble(5.0..10.0) } } ``` --- ### `playerKilledEntity` **Description:** Triggers when a player kills an entity. **Properties:** - `entity`: The entity that was killed. - `killingBlow`: Details about the killing blow. **Example:** ```kotlin playerKilledEntity("kill_mob") { entity { conditions { entityProperties { type(EntityTypes.ZOMBIE) } } } } ``` --- ### `playerShearedEquipment` **Description:** Triggers after a player shears equipment off of a mob, such as wolf armor. **Properties:** - `entity`: The entity whose equipment was sheared. - `item`: The item of equipment that was sheared off. **Example:** ```kotlin playerShearedEquipment("shear_wolf_armor") { entity { type(EntityTypes.WOLF) } item { item(Items.LEATHER) } } ``` ### `recipeCrafted` **Description:** Triggers when a recipe is crafted. **Properties:** - `recipeId`: The ID of the crafted recipe. - `ingredients`: The ingredients used in the recipe. **Example:** ```kotlin recipeCrafted("craft_diamond") { recipeId = Recipes.DIAMOND ingredient(Items.DIAMOND) { components { damage(0) } } } ``` --- ### `recipeUnlocked` **Description:** Triggers when a recipe is unlocked. **Properties:** - `recipe`: The recipe that was unlocked. **Example:** ```kotlin recipeUnlocked("unlock_recipe", Recipes.DIAMOND) ``` --- ### `rideEntityInLava` **Description:** Triggers when riding an entity in lava. **Properties:** - `distance`: The distance traveled while riding in lava. - `startPosition`: The starting position before riding. **Example:** ```kotlin rideEntityInLava("lava_ride") { distance { horizontal(10f) } startPosition { position { y = rangeOrInt(100..200) } } } ``` --- ### `shotCrossbow` **Description:** Triggers when shooting a crossbow. **Properties:** - `item`: The crossbow item that was shot. **Example:** ```kotlin shotCrossbow("shoot_crossbow") { item { item(Items.CROSSBOW) enchantments { enchantment(Enchantments.MULTISHOT, 1) } } } ``` --- ### `sleptInBed` **Description:** Triggers when a player sleeps in a bed. **Properties:** _None._ **Example:** ```kotlin sleptInBed("sleep_in_bed") ``` --- ### `slideDownBlock` **Description:** Triggers when sliding down a block. **Properties:** - `block`: The block being slid down. **Example:** ```kotlin slideDownBlock("slide_down") { block { blocks(Blocks.SNOW_BLOCK) } } ``` --- ### `startedRiding` **Description:** Triggers when a player starts riding an entity. **Properties:** _None._ **Example:** ```kotlin startedRiding("ride_horse") { conditions { vehicle { type(EntityTypes.HORSE) } } } ``` --- ### `summonedEntity` **Description:** Triggers when an entity is summoned. **Properties:** - `entity`: The entity that was summoned. **Example:** ```kotlin summonedEntity("summon_iron_golem") { entity { type(EntityTypes.IRON_GOLEM) } } ``` --- ### `tameAnimal` **Description:** Triggers when an animal is tamed. **Properties:** - `entity`: The animal that was tamed. **Example:** ```kotlin tameAnimal("tame_wolf") { entity { type(EntityTypes.WOLF) } } ``` --- ### `targetHit` **Description:** Triggers when a target block is hit. **Properties:** - `signalStrength`: The strength of the signal when the target is hit. - `projectile`: The projectile used to hit the target. **Example:** ```kotlin targetHit("hit_target") { signalStrength = rangeOrInt(1..15) projectile { conditions { entityProperties { type(EntityTypes.ARROW) } } } } ``` --- ### `thrownItemPickedUpByEntity` **Description:** Triggers when a thrown item is picked up by an entity. **Properties:** - `entity`: The entity that picked up the item. - `item`: The item that was picked up. **Example:** ```kotlin thrownItemPickedUpByEntity("feed_animal") { entity { type(EntityTypes.COW) } item { item(Items.WHEAT) } } ``` --- ### `thrownItemPickedUpByPlayer` **Description:** Triggers when a thrown item is picked up by a player. **Properties:** - `entity`: The entity that picked up the item. - `item`: The item that was picked up. **Example:** ```kotlin thrownItemPickedUpByPlayer("catch_trident") { item { item(Items.TRIDENT) } } ``` --- ### `tick` **Description:** Triggers every tick (20 times per second). **Properties:** - `conditions`: Conditions that must be met for the trigger to activate. **Example:** ```kotlin tick("game_tick") { conditions { timeCheck(6000..18000) // Daytime only } } ``` --- ### `usedEnderEye` **Description:** Triggers when an ender eye is used. **Properties:** - `distance`: The distance traveled using the ender eye. **Example:** ```kotlin usedEnderEye("find_stronghold") { distance { horizontal(100f) } } ``` --- ### `usedTotem` **Description:** Triggers when a totem is used. **Properties:** - `item`: The totem item that was used. **Example:** ```kotlin usedTotem("save_life") { item { item(Items.TOTEM_OF_UNDYING) } } ``` --- ### `usingItem` **Description:** Triggers while using an item. **Properties:** - `item`: The item being used. **Example:** ```kotlin usingItem("shield_block") { item { items = listOf(Items.SHIELD) } } ``` --- ### `villagerTrade` **Description:** Triggers when a villager trades. **Properties:** - `item`: The item involved in the trade. - `villager`: The villager involved in the trade. **Example:** ```kotlin villagerTrade("trade") { item { item(Items.EMERALD) } villager { conditions { entityProperties { team = "villager" } } } } ``` --- ### `voluntaryExile` **Description:** Triggers when a player causes a raid in a village. **Properties:** - `location`: The location where the raid occurred. **Example:** ```kotlin voluntaryExile("raid_village") { conditions { location { dimension = Dimensions.OVERWORLD } } } ``` --- Each trigger example demonstrates the basic usage with common properties and conditions. You can customize these triggers by adding more conditions and requirements to suit your specific advancement needs. --- ## Dialogs --- root: .components.layouts.MarkdownLayout title: Dialogs nav-title: Dialogs description: Create interactive dialog screens in Minecraft with Kore's comprehensive dialog system. keywords: minecraft, datapack, kore, dialogs, ui, interactive, forms, confirmation, notice date-created: 2025-09-18 date-modified: 2025-09-18 routeOverride: /docs/data-driven/dialogs --- # Dialogs Minecraft includes a powerful dialog system that allows creating interactive modal windows for displaying information and receiving player input. Dialogs are native Minecraft features introduced in Java Edition 1.21.6 that enable sophisticated user interfaces within the game. With **Kore**, you can easily create and manage these dialogs using a comprehensive Kotlin DSL that maps directly to Minecraft's dialog format. Minecraft's dialog system supports various interaction types including: - Displaying rich text with formatting and clickable elements - Receiving player input through text fields, toggles, sliders, and option selections - Executing commands via action buttons (with appropriate permissions) - Navigating between multiple dialogs using nested structures - Integration with the pause menu and quick actions hotkey For the vanilla reference, see the [Minecraft Wiki – Dialog](https://minecraft.wiki/w/Dialog) and [Commands/dialog](https://minecraft.wiki/w/Commands/dialog). ## Minecraft Dialog System Overview Minecraft dialogs consist of three main elements: - **Header**: Contains the title and warning button - **Body elements**: Labels, inputs, buttons, and submit actions (scrollable if needed) - **Optional footer**: Confirmation buttons and submit actions When a dialog opens, player controls are temporarily disabled until the user exits through an action button, the Escape key, or the warning button. In single-player mode, dialogs can be configured to pause the game and trigger an autosave. ## Set Up Your Data Pack Function Begin by creating a function within your `DataPack` where you'll define your dialogs: ```kotlin fun DataPack.createDialogs() { // Your dialog definitions will go here } ``` ## Initialize the Dialogs Block Use the `dialogBuilder` to start defining your dialogs: ```kotlin val myDialog = dialogBuilder.confirmation("welcome", "Welcome!") { // Define dialog properties here } ``` Or use the `dialogs` DSL: ```kotlin dialogs { confirmation("my-dialog", "Title!") { // Define dialog properties here } } ``` ## Dialog Types Minecraft currently supports five different dialog types: ### Confirmation Dialog A dialog with two action buttons (yes/no) for binary choices: ```kotlin val confirmDialog = dialogBuilder.confirmation("delete_world", "Delete World?") { afterAction = AfterAction.WAIT_FOR_RESPONSE externalTitle("Delete", Color.RED) pause = true bodies { plainMessage("Are you sure you want to delete this world? This action cannot be undone.") } yes("Delete") { action { runCommand { say("World deleted!") } } } no("Cancel") { action { suggestChatMessage("Cancelled deletion") } } } ``` ### Notice Dialog A simple dialog with a single action button for displaying information: ```kotlin val noticeDialog = dialogBuilder.notice("achievement", "Achievement Unlocked!") { bodies { item(Items.DIAMOND_SWORD) { description = ItemDescription(textComponent("Your first diamond tool!")) showTooltip = true } plainMessage("You've crafted your first diamond sword!") } action("Awesome!") { tooltip("Click to continue") action { dynamicCustom("celebrate") { this["achievement"] = "first_diamond_tool" } } } } ``` ### Multi Action Dialog A dialog with multiple action buttons arranged in columns, perfect for menus: ```kotlin val menuDialog = dialogBuilder.multiAction("main_menu", "Server Menu") { columns = 3 inputs { text("player_name", "Your Name") { maxLength = 16 initial = "Steve" } numberRange("difficulty", "Difficulty", range = 1..10, initial = 5) { step = 1f } boolean("pvp_enabled", "Enable PVP") { initial = false onTrue = "PVP On" onFalse = "PVP Off" } } actions { action("Start Game") { action { runCommand { say("Game starting with settings!") } } } action("Settings") { action { openUrl("https://example.com/settings") } } action("Quit") { action { dynamicRunCommand { kick(allPlayers(), textComponent("Thanks for playing!")) } } } } } ``` ### Dialog List A dialog that displays a scrollable list of other dialogs: ```kotlin val listDialog = dialogBuilder.dialogList("dialog_menu", "Available Dialogs") { columns = 2 buttonWidth = 200 dialogs(confirmDialog, noticeDialog, menuDialog) // or use a tag: // dialogs(Tags.Dialog.PAUSE_SCREEN_ADDITIONS) exitAction("Back to Game") { action { dynamicRunCommand { say("Returning to game...") } } } } ``` ### Server Links Dialog A specialized dialog for displaying server links (configured server-side): ```kotlin val linksDialog = dialogBuilder.serverLinks("server_links", "Server Links") { buttonWidth = 150 columns = 3 exitAction("Close") { action { dynamicRunCommand { say("Links closed") } } } } ``` ## Dialog Properties All dialogs share common properties that can be customized: ### Basic Properties ```kotlin dialogBuilder.confirmation("example", "Title") { // External title shown on buttons leading to this dialog externalTitle("Custom Button Text", Color.AQUA) // Action performed after dialog interactions afterAction = AfterAction.WAIT_FOR_RESPONSE // or CLOSE // Whether dialog can be dismissed with Escape key canCloseWithEscape = true // Whether to pause the game in single-player pause = true } ``` ### After Actions Control what happens after dialog interactions: - `AfterAction.NONE` - Do nothing - `AfterAction.CLOSE` - Close the dialog (default) - `AfterAction.WAIT_FOR_RESPONSE` - Keep dialog open awaiting response ## Body Elements Dialogs can contain rich content between the title and action buttons: ### Plain Messages Display text content: ```kotlin bodies { plainMessage("Welcome to our server!") { width = 300 } plainMessage(textComponent("Colored text", Color.GREEN)) } ``` ### Items Display items with descriptions: ```kotlin bodies { item(Items.ENCHANTED_BOOK) { description = ItemDescription(textComponent("A mysterious tome")) showTooltip = true showDecorations = false height = 64 width = 64 } } ``` ## Input Controls Multi-action dialogs can include various input controls for user interaction: ### Text Input Single-line or multi-line text input: ```kotlin inputs { text("username", "Username") { maxLength = 20 initial = "Player" width = 200 labelVisible = true } text("bio", "Biography") { multiline(maxLines = 5, height = 100) maxLength = 500 } } ``` ### Number Range Slider controls for numeric input: ```kotlin inputs { numberRange("volume", "Volume", range = 0..100, initial = 50) { step = 5f labelFormat = "Volume: %d%%" width = 250 } // Float ranges also supported numberRange("speed", "Speed", range = 0.1f..2.0f, initial = 1.0f) { step = 0.1f } } ``` ### Boolean Toggle Checkbox-style boolean input: ```kotlin inputs { boolean("notifications", "Enable Notifications") { initial = true onTrue = "✓ Enabled" onFalse = "✗ Disabled" } } ``` ### Single Option Dropdown-style selection: ```kotlin inputs { singleOption("gamemode", "Game Mode") { width = 200 labelVisible = true option("survival", "Survival", initial = true) option("creative", "Creative") option("adventure", "Adventure") option("spectator", "Spectator") } } ``` ## Actions Dialog actions define what happens when buttons are clicked: ### Available Action Types ```kotlin action { // Run a command runCommand { say("Hello world!") } // Suggest a chat message suggestChatMessage("/gamemode creative") // Open a URL openUrl("https://minecraft.net") // Copy text to clipboard copyToClipboard("Server IP: mc.example.com") // Change page in a book changePage(5) // Dynamic commands with macros named after the inputs dynamicRunCommand { say("Player name is ${macro('username')}") } // Custom dynamic actions, for sending custom packets for server plugins/mods dynamicCustom("custom_action") { this["data"] = "value" this["count"] = 42 } } ``` ### Action Properties Enhance actions with labels, tooltips, and sizing: ```kotlin action("My Button") { tooltip("Click me for awesome results!") width = 150 action { runCommand { say("Button clicked!") } } } ``` ## Using Dialogs in Commands Commands can show and clear dialogs to players, using a reference or an inline dialog: ```kotlin load { // Show dialog to specific players dialogShow(allPlayers(), myDialog) // Create and show dialog inline dialogShow(allPlayers()) { confirmation("inline_dialog", "Quick Confirmation") { yes("Yes") { action { runCommand { say("Yes selected") } } } no("No") { action { runCommand { say("No selected") } } } } } // Clear dialogs dialogClear(allPlayers()) } ``` ## Advanced Examples ### Complex Form Dialog ```kotlin val registrationForm = dialogBuilder.multiAction("register", "Player Registration") { columns = 1 bodies { plainMessage("Welcome! Please fill out your information:") } inputs { text("display_name", "Display Name") { maxLength = 32 labelVisible = true } text("email", "Email Address") { maxLength = 100 } numberRange("age", "Age", range = 13..99, initial = 18) { step = 1f } singleOption("region", "Region") { option("na", "North America") option("eu", "Europe") option("as", "Asia") option("other", "Other") } boolean("newsletter", "Subscribe to Newsletter") { initial = false } text("comments", "Additional Comments") { multiline(maxLines = 3, height = 80) maxLength = 200 } } actions { action("Register") { action { dynamicRunCommand { say("Registration submitted!") give(allPlayers(), Items.WRITTEN_BOOK) } } } action("Cancel") { action { suggestChatMessage("Registration cancelled") } } } } ``` ### Interactive Tutorial System ```kotlin val tutorialDialog = dialogBuilder.dialogList("tutorials", "Tutorial Menu") { columns = 2 buttonWidth = 180 bodies { plainMessage("Choose a tutorial to begin:") item(Items.BOOK) { description = ItemDescription(textComponent("Learn the basics")) } } // Reference other tutorial dialogs dialogs( basicTutorial, advancedTutorial, pvpTutorial ) exitAction("Skip Tutorials") { action { runCommand { advancement.grant(allPlayers(), AdvancementArgument("tutorial:skipped")) } } } } ``` ## Best Practices 1. **Keep dialogs focused**: Each dialog should serve a single, clear purpose 2. **Use appropriate dialog types**: - Confirmation for yes/no decisions - Notice for information display - Multi-action for complex forms or menus 3. **Provide clear labels**: Make button and input labels descriptive 4. **Include tooltips**: Add helpful tooltips for complex actions 5. **Handle edge cases**: Provide cancel/exit options where appropriate ## Integration with Other Systems Dialogs work seamlessly with other Kore features: ```kotlin val conditionalDialog = dialogBuilder.confirmation("weather_change", "Change Weather?") { // Only show if it's currently raining yes("Make Sunny") { action { runCommand { weatherClear() } } } no("Keep Current") { action { suggestChatMessage("Weather unchanged") } } } val firstDeathScoreboard = "first_death" advancement("first_death") { criteria { tick("check_each_ticks") { conditions { entityProperties { nbt { this["Health"] = 0f } } } } } display(Items.AIR) { announceToChat = false hidden = true } rewards { function { scoreboard.objective(self(), firstDeathScoreboard).set(1) execute { ifCondition { score(self(), firstDeathScoreboard) equalTo 1 } run { dialogShow(self(), conditionalDialog) scoreboard.objective(self(), firstDeathScoreboard).set(2) // Prevent re-triggering } } } } } // Integration with advancements load { // Define the objective scoreboard.objective(firstDeathScoreboard).create(ScoreboardCriteria.DUMMY) } ``` ## See also - [Advancements](./advancements) - [Components](./components) - [Predicates](./predicates) --- ## Enchantments --- root: .components.layouts.MarkdownLayout title: Enchantments nav-title: Enchantments description: Create custom Minecraft enchantments using Kore's type-safe Kotlin DSL with support for all vanilla effect components and level-based values. keywords: minecraft, datapack, kore, enchantments, effects, custom enchantments date-created: 2025-03-02 date-modified: 2026-02-03 routeOverride: /docs/data-driven/enchantments --- # Enchantments Enchantments are data-driven definitions that modify item behavior, apply effects, change damage calculations, and alter various game mechanics. In Minecraft Java Edition 1.21+, enchantments are fully customizable through data packs, allowing you to create entirely new enchantments with unique effects. ## Overview Custom enchantments have several key characteristics: - **Data-driven**: Defined as JSON files in data packs, not hardcoded - **Effect components**: Modular system of 30+ effect types - **Level-based scaling**: Values can scale with enchantment level - **Slot-aware**: Effects apply based on equipment slot configuration - **Conditional**: Effects can have predicate requirements ### Enchantment Properties Every enchantment defines these core properties: | Property | Description | |-------------------------|-----------------------------------------------------| | `description` | Text component displayed on items | | `supported_items` | Items that can receive the enchantment | | `primary_items` | Items where enchantment appears in enchanting table | | `exclusive_set` | Incompatible enchantments | | `weight` | Probability weight (1-1024) | | `max_level` | Maximum level (1-255) | | `min_cost` / `max_cost` | Enchanting table level requirements | | `anvil_cost` | Base cost for anvil application | | `slots` | Equipment slots where effects apply | | `effects` | Effect components that define behavior | ## File Structure Enchantments are stored as JSON files in data packs at: ``` data//enchantment/.json ``` For complete JSON specification, see the [Minecraft Wiki - Enchantment definition](https://minecraft.wiki/w/Enchantment_definition). ## Creating Enchantments Use the `enchantment` builder function to create enchantments in Kore: ```kotlin dataPack("my_datapack") { enchantment("fire_aspect_plus") { description("Fire Aspect+") supportedItems(Items.DIAMOND_SWORD, Items.NETHERITE_SWORD) primaryItems(Tags.Item.SWORDS) exclusiveSet(Enchantments.FIRE_ASPECT) weight = 2 maxLevel = 3 minCost(15, 10) // base 15, +10 per level maxCost(65, 10) anvilCost = 4 slots(EquipmentSlot.MAINHAND) effects { // Define effects here } } } ``` This generates `data/my_datapack/enchantment/fire_aspect_plus.json`. ## Basic Properties ### Description The text shown on enchanted items: ```kotlin enchantment("test") { // Simple string description("Test Enchantment") // Or with text component for formatting description(textComponent("Test") { color = Color.GOLD }) } ``` ### Supported and Primary Items ```kotlin enchantment("bow_enchant") { // Items that can have this enchantment (anvil/commands) supportedItems(Items.BOW, Items.CROSSBOW) // Items where it appears in enchanting table (subset of supported) primaryItems(Tags.Item.BOW_ENCHANTABLE) } ``` ### Exclusive Set Enchantments that cannot coexist: ```kotlin enchantment("protection_variant") { exclusiveSet(Tags.Enchantment.ARMOR_EXCLUSIVE) // Or individual enchantments exclusiveSet(Enchantments.PROTECTION, Enchantments.FIRE_PROTECTION) } ``` ### Cost and Weight ```kotlin enchantment("rare_enchant") { weight = 1 // Very rare (compare to Mending: 2, Unbreaking: 5) maxLevel = 5 // Level cost formula: base + (level - 1) * per_level_above_first minCost(base = 1, perLevelAboveFirst = 11) // 1, 12, 23, 34, 45 maxCost(base = 21, perLevelAboveFirst = 11) // 21, 32, 43, 54, 65 anvilCost = 8 // Expensive to combine } ``` ### Equipment Slots Where the enchantment's effects apply: ```kotlin enchantment("armor_enchant") { slots(EquipmentSlot.HEAD, EquipmentSlot.CHEST, EquipmentSlot.LEGS, EquipmentSlot.FEET) } enchantment("weapon_enchant") { slots(EquipmentSlot.MAINHAND, EquipmentSlot.OFFHAND) } ``` Available slots: `ANY`, `HAND`, `MAINHAND`, `OFFHAND`, `ARMOR`, `FEET`, `LEGS`, `CHEST`, `HEAD`, `BODY`, `SADDLE`. ## Effect Components Effects define what the enchantment actually does. Kore supports all vanilla effect components. ### Value Effect Components These components modify numeric values with level-based scaling: | Component | Description | |-----------------------------|------------------------------------| | `ammoUse` | Ammunition consumption | | `armorEffectiveness` | Armor effectiveness multiplier | | `blockExperience` | XP from breaking blocks | | `crossbowChargeTime` | Crossbow charge time | | `damage` | Bonus attack damage | | `damageProtection` | Damage reduction (max 80% total) | | `equipmentDrops` | Equipment drop chance | | `fishingLuckBonus` | Fishing luck bonus | | `fishingTimeReduction` | Fishing speed bonus | | `itemDamage` | Durability loss multiplier | | `knockback` | Knockback strength | | `mobExperience` | XP from killing mobs | | `projectileCount` | Projectiles fired | | `projectilePiercing` | Targets pierced | | `projectileSpread` | Accuracy spread in degrees | | `repairWithXp` | Durability repaired per XP | | `smashDamagePerFallenBlock` | Mace bonus damage per block fallen | | `tridentReturnAcceleration` | Trident return speed | | `tridentSpinAttackStrength` | Riptide attack strength | ```kotlin effects { // Simple damage bonus damage { add(linearLevelBased(2, 0.5)) // +2 base, +0.5 per level } // Protection with conditions damageProtection { add(constantLevelBased(4)) { requirements { damageType(DamageTypes.IN_FIRE) } } } // Multiple value modifications armorEffectiveness { add(5) multiply(1.5) set(10) removeBinomial(0.5) // 50% chance to remove 1 allOf { add(2) multiply(1.2) } } } ``` ### Entity Effect Components These components trigger actions on entities: | Component | Description | |----------------------|-----------------------------------------------| | `hitBlock` | After hitting a block with the enchanted item | | `postAttack` | After damaging an entity | | `postPiercingAttack` | After a piercing attack with an item | | `projectileSpawned` | When a projectile is created | | `tick` | Every game tick while equipped | ```kotlin effects { // Apply effects when hitting blocks hitBlock { applyMobEffect(Effects.SPEED) { minDuration(5) maxDuration(10) minAmplifier(0) maxAmplifier(2) } } // Periodic effects tick { damageEntity(DamageTypes.MAGIC, 0.5, 1.0) } // Post-attack effects (like Thorns) postAttack { damageEntity( PostAttackSpecifier.ATTACKER, PostAttackSpecifier.VICTIM, DamageTypes.THORNS, 1, 3 ) } } ``` ### Special Effect Components | Component | Description | |--------------------------|--------------------------------------| | `attributes` | Applies attribute modifiers | | `crossbowChargingSounds` | Custom crossbow sounds | | `damageImmunity` | Grants immunity to damage types | | `preventArmorChange` | Prevents removing from armor slot | | `preventEquipmentDrop` | Prevents item from dropping on death | | `tridentSound` | Custom trident sounds | ```kotlin effects { // Damage immunity (like totems) damageImmunity { sound { requirements { damageType(DamageTypes.FALLING_BLOCK) } } } // Curse-like effects preventEquipmentDrop() preventArmorChange() // Attribute modifiers attributes { attribute( "bonus_speed", name, Attributes.MOVEMENT_SPEED, AttributeModifierOperation.ADD_MULTIPLIED_BASE, 0.1 // +10% speed ) } // Custom sounds crossbowChargingSounds { crossbowChargingSound { start(SoundEvents.Item.Crossbow.QUICK_CHARGE_1) mid(SoundEvents.Item.Crossbow.QUICK_CHARGE_2) end(SoundEvents.Item.Crossbow.QUICK_CHARGE_3) } } } ``` ## Entity Effects Entity effects are actions that can be triggered by effect components: ### Apply Impulse ```kotlin applyImpulse( direction = Vec3f(0f, 1f, 0f), // local coordinates applied to entity look vector coordinateScale = Vec3f(1f, 1f, 1f), // world-space scaling per axis magnitude = constantLevelBased(2) // final scaling ) ``` ### Apply Mob Effect ```kotlin applyMobEffect(Effects.SLOWNESS, Effects.WEAKNESS) { minDuration(5) maxDuration(linearLevelBased(5, 5)) minAmplifier(0) maxAmplifier(constantLevelBased(1)) } ``` ### Damage Entity ```kotlin damageEntity(DamageTypes.MAGIC, minDamage = 1, maxDamage = 5) ``` ### Explode ```kotlin explode( attributeToUser = true, createFire = false, blockInteraction = BlockInteraction.TNT, smallParticle = Particles.EXPLOSION, largeParticle = Particles.EXPLOSION_EMITTER, sound = Sounds.Entity.Generic.EXPLODE ) { radius(linearLevelBased(2, 1)) } ``` ### Ignite ```kotlin ignite(duration = linearLevelBased(4, 4)) // seconds ``` ### Play Sound ```kotlin playSound(SoundEvents.Entity.Firework.LAUNCH, volume = 1f) ``` ### Replace Block/Disk ```kotlin replaceBlock(simpleStateProvider(Blocks.FIRE)) { offset(0, 1, 0) triggerGameEvent = GameEvents.BLOCK_PLACE } replaceDisk(simpleStateProvider(Blocks.ICE)) { radius(linearLevelBased(2, 1)) height(1) } ``` ### Spawn Particles ```kotlin spawnParticles( Particles.FLAME, horizontalPositionType = ParticlePositionType.IN_BOUNDING_BOX, verticalPositionType = ParticlePositionType.IN_BOUNDING_BOX ) { horizontalVelocity(base = 0.1f, movementScale = 0f) verticalVelocity(base = 0.5f, movementScale = 0f) speed(0.5f) } ``` ### Run Function ```kotlin runFunction(FunctionArgument("on_hit", "my_datapack")) ``` ### Summon Entity ```kotlin summonEntity(EntityTypes.LIGHTNING_BOLT) ``` ### Change Item Damage ```kotlin changeItemDamage(linearLevelBased(1, 1)) // Durability consumed ``` ## Level-Based Values Level-based values allow effects to scale with enchantment level: | Type | Description | Example | |--------------------------------------|-------------------|---------------------------------------------| | `clampedLevelBased(value, min, max)` | Clamped range | `clampedLevelBased(linear, 1.0, 10.0)` | | `constantLevelBased(value)` | Fixed value | `constantLevelBased(5)` | | `exponentLevelBased(base, power)` | Exponential | `exponentLevelBased(1, 5)` → 1, 5, 25... | | `fractionLevelBased(num, denom)` | Fractional | `fractionLevelBased(1, 2)` → 0.5, 1, 1.5... | | `levelsSquaredLevelBased(base)` | Quadratic scaling | `levelsSquaredLevelBased(1)` → 1, 4, 9... | | `linearLevelBased(base, perLevel)` | Linear scaling | `linearLevelBased(2, 0.5)` → 2, 2.5, 3... | | `lookupLevelBased(list, fallback)` | Lookup table | `lookupLevelBased(listOf(1, 3, 7), 10)` | ```kotlin effects { damage { // Linear: 2 + 0.5 per level → 2, 2.5, 3, 3.5, 4 for levels 1-5 add(linearLevelBased(2, 0.5)) } blockExperience { // Complex combination allOf { add(clampedLevelBased(linearLevelBased(1, 2), 0.0, 10.0)) multiply(levelsSquaredLevelBased(0.1)) } } } ``` ## Requirements (Conditions) Effect components can have requirements that must be met: ```kotlin effects { damage { add(5) { requirements { // Only in rain weatherCheck(raining = true) } } } damageProtection { add(4) { requirements { // Only against fire damage damageType(DamageTypes.IN_FIRE, DamageTypes.ON_FIRE) } } } postAttack { applyMobEffect( PostAttackSpecifier.ATTACKER, PostAttackSpecifier.VICTIM, Effects.POISON ) { requirements { // Only against undead entityProperties { type(EntityTypes.ZOMBIE, EntityTypes.SKELETON) } } } } } ``` ## Full Example ```kotlin dataPack("custom_enchants") { enchantment("vampiric") { description(textComponent("Vampiric") { color = Color.DARK_RED }) supportedItems(Tags.Item.SWORDS) primaryItems(Tags.Item.SWORD_ENCHANTABLE) exclusiveSet(Enchantments.MENDING) weight = 2 maxLevel = 3 minCost(20, 15) maxCost(50, 15) anvilCost = 8 slots(EquipmentSlot.MAINHAND) effects { // Lifesteal on hit postAttack { applyMobEffect( PostAttackSpecifier.ATTACKER, PostAttackSpecifier.ATTACKER, Effects.INSTANT_HEALTH ) { minAmplifier(0) maxAmplifier(0) minDuration(1) maxDuration(1) requirements { randomChance(linearLevelBased(0.1, 0.1)) // 10/20/30% chance } } } // Bonus damage to undead damage { add(linearLevelBased(2, 1)) { requirements { entityProperties { type(Tags.EntityType.UNDEAD) } } } } // Visual feedback hitBlock { spawnParticles( Particles.CRIMSON_SPORE, horizontalPositionType = ParticlePositionType.ENTITY_POSITION, verticalPositionType = ParticlePositionType.ENTITY_POSITION ) { speed(0.2f) } } } } } ``` ### Generated JSON ```json { "description": { "text": "Vampiric", "color": "dark_red" }, "supported_items": "#minecraft:swords", "primary_items": "#minecraft:sword_enchantable", "exclusive_set": "minecraft:mending", "weight": 2, "max_level": 3, "min_cost": { "base": 20, "per_level_above_first": 15 }, "max_cost": { "base": 50, "per_level_above_first": 15 }, "anvil_cost": 8, "slots": [ "mainhand" ], "effects": { "minecraft:post_attack": [ { "enchanted": "attacker", "affected": "attacker", "effect": { "type": "minecraft:apply_mob_effect", "to_apply": "minecraft:instant_health", "min_amplifier": 0, "max_amplifier": 0, "min_duration": 1, "max_duration": 1 }, "requirements": { "condition": "minecraft:random_chance", "chance": { "type": "minecraft:linear", "base": 0.1, "per_level_above_first": 0.1 } } } ], "minecraft:damage": [ { "effect": { "type": "minecraft:add", "value": { "type": "minecraft:linear", "base": 2, "per_level_above_first": 1 } }, "requirements": { "condition": "minecraft:entity_properties", "predicate": { "type": "#minecraft:undead" } } } ] } } ``` ## Enchantment Providers Enchantment providers are used by enchanting tables and loot functions to select enchantments: ```kotlin enchantmentProvider("custom_table") { single { enchantment = Enchantments.SHARPNESS } } enchantmentProvider("cost_based") { byCost { // Configuration for cost-based selection } } ``` ## Best Practices 1. **Balance carefully** - Test enchantment power at all levels; use appropriate weights 2. **Use exclusive sets** - Prevent overpowered combinations with incompatible enchantments 3. **Scale appropriately** - Use level-based values that provide meaningful progression 4. **Add requirements** - Use conditions to create situational bonuses 5. **Consider slots** - Ensure effects only apply in appropriate equipment slots 6. **Test thoroughly** - Verify effects work correctly in all contexts (PvP, PvE, etc.) ## See Also - [Predicates](./predicates) - Conditions for enchantment effect requirements - [Components](../concepts/components) - Item components and matchers - [Loot Tables](./loot-tables) - Apply enchantments via loot functions - [Item Modifiers](./item-modifiers) - Add enchantments at runtime - [Tags](./tags) - Use enchantment and item tags ### External Resources - [Minecraft Wiki: Enchantment definition](https://minecraft.wiki/w/Enchantment_definition) - Official JSON format reference - [Minecraft Wiki: Enchanting](https://minecraft.wiki/w/Enchanting) - Enchanting mechanics overview --- ## Item Modifiers --- root: .components.layouts.MarkdownLayout title: Item Modifiers nav-title: Item Modifiers description: Transform item stacks using Kore's type-safe DSL for loot functions - set counts, add enchantments, copy data, and more. keywords: minecraft, datapack, kore, item modifiers, loot functions, /item modify, components date-created: 2025-08-11 date-modified: 2026-02-03 routeOverride: /docs/data-driven/item-modifiers --- # Item Modifiers Item modifiers (also called loot functions) transform item stacks by adjusting counts, adding enchantments, copying data, setting components, and more. They can be defined as standalone JSON files referenced by commands, or used inline within loot tables. ## Overview Item modifiers have several key characteristics: - **Composable**: Chain multiple functions together for complex transformations - **Conditional**: Each function can have predicate conditions - **Context-aware**: Access loot context for killer, tool, block entity, etc. - **Reusable**: Define once as a file, reference anywhere ### Common Use Cases | Use Case | Functions | |----------------------|-----------------------------------------------------------| | Set stack count | `setCount` | | Add enchantments | `enchantRandomly`, `enchantWithLevels`, `setEnchantments` | | Modify durability | `setDamage` | | Copy NBT/components | `copyComponents`, `copyCustomData`, `copyName` | | Set name/lore | `setName`, `setLore` | | Create explorer maps | `explorationMap` | | Fill containers | `setContents`, `setLootTable` | | Apply formulas | `applyBonus`, `enchantedCountIncrease` | ## File Structure Item modifiers are stored as JSON files in data packs at: ``` data//item_modifier/.json ``` For complete JSON specification, see the [Minecraft Wiki - Item modifier](https://minecraft.wiki/w/Item_modifier). ## Creating Item Modifiers Use the `itemModifier` builder function to create item modifiers in Kore: ```kotlin dataPack("my_datapack") { val modifier = itemModifier("fortune_bonus") { enchantRandomly { options += Enchantments.FORTUNE } setCount(uniform(1f, 5f)) } } ``` This generates `data/my_datapack/item_modifier/fortune_bonus.json`. ## Using Item Modifiers ### With Commands Apply modifiers to items using the `/item modify` command: ```kotlin load { items { // Modify item in player's mainhand modify(self(), WEAPON.MAINHAND, modifier) // Modify item in container modify(block(0, 64, 0), slot(0), modifier) } } ``` ### In Loot Tables Use functions directly in loot tables at table, pool, or entry level: ```kotlin lootTable("treasure") { // Table-level functions (applied to all drops) functions { enchantRandomly() } pool { // Pool-level functions functions { setCount(uniform(1f, 3f)) } entries { item(Items.DIAMOND) { // Entry-level functions functions { setName("Lucky Diamond") } } } } } ``` ## Function Reference ### Count and Damage #### setCount Sets or modifies the stack count: ```kotlin itemModifier("set_count") { // Exact count setCount(5f) // Random range setCount(uniform(1f, 10f)) // Add to current count setCount(5f, add = true) // With condition setCount(10f) { conditions { killedByPlayer() } } } ``` #### setDamage Sets item durability (1.0 = full, 0.0 = broken): ```kotlin itemModifier("damage") { // Set to 80% durability setDamage(0.8f) // Random damage setDamage(uniform(0.5f, 1.0f)) // Add to current damage setDamage(-0.1f, add = true) // Repair 10% } ``` #### limitCount Clamps stack count to a range: ```kotlin itemModifier("limit") { // Exact limit limitCount(64) // Range limitCount(providersRange(min = constant(1f), max = constant(32f))) } ``` ### Enchantments #### enchantRandomly Adds a random enchantment: ```kotlin itemModifier("random_enchant") { // Any enchantment enchantRandomly() // From specific list enchantRandomly { options += Enchantments.SHARPNESS options += Enchantments.SMITE options += Enchantments.BANE_OF_ARTHROPODS } // Only compatible enchantments enchantRandomly(onlyCompatible = true) } ``` #### enchantWithLevels Enchants as if using an enchanting table: ```kotlin itemModifier("table_enchant") { // Fixed level enchantWithLevels(levels = constant(30f)) // Random level range enchantWithLevels(levels = uniform(20f, 39f)) // Limit to specific enchantments enchantWithLevels(Enchantments.PROTECTION, levels = constant(30f)) } ``` #### setEnchantments Sets specific enchantments and levels: ```kotlin itemModifier("specific_enchants") { setEnchantments { enchantment(Enchantments.SHARPNESS, 5) enchantment(Enchantments.UNBREAKING, 3) enchantment(Enchantments.MENDING, 1) } } ``` #### enchantedCountIncrease Increases count based on enchantment level (like Looting): ```kotlin itemModifier("looting_bonus") { enchantedCountIncrease(Enchantments.LOOTING, count = 1f, limit = 5) } ``` ### Names and Lore #### setName Sets the item's display name: ```kotlin itemModifier("named") { // Simple string setName("Legendary Sword") // Text component with formatting setName(textComponent("Legendary Sword") { color = Color.GOLD bold = true }) // Set item name vs custom name setName("Base Name") { target = SetNameTarget.ITEM_NAME // or CUSTOM_NAME } } ``` #### setLore Sets or modifies item lore: ```kotlin itemModifier("lore") { setLore { lore("First line", Color.GRAY) lore("Second line", Color.DARK_GRAY) // Insert at specific position mode(Mode.INSERT, offset = 0) } } ``` ### Components #### setComponents Directly set item components: ```kotlin itemModifier("components") { setComponents { customName(textComponent("Custom Item", Color.GOLD)) damage(10) unbreakable(showInTooltip = false) // Remove component with ! !food {} } } ``` #### copyComponents Copy components from a source: ```kotlin itemModifier("copy_from_block") { copyComponents { source = Source.BLOCK_ENTITY // Include specific components include(ItemComponentTypes.CUSTOM_NAME, ItemComponentTypes.LORE) // Or exclude specific components exclude(ItemComponentTypes.DAMAGE) } } ``` #### copyName Copy entity/block name to item: ```kotlin itemModifier("named_drop") { copyName(Source.BLOCK_ENTITY) // Or from entity copyName(Source.THIS) copyName(Source.KILLER) } ``` #### copyCustomData Copy NBT data to custom_data component: ```kotlin itemModifier("copy_nbt") { copyCustomData { source(Source.BLOCK_ENTITY) operations { operation("Items", "BlockItems", CopyOperation.REPLACE) operation("Lock", "OriginalLock", CopyOperation.MERGE) } } } ``` ### Container Contents #### setContents Fill container items (bundles, shulker boxes): ```kotlin itemModifier("filled_bundle") { setContents(ContentComponentTypes.BUNDLE_CONTENTS) { entries { item(Items.DIAMOND) { functions { setCount(16f) } } item(Items.EMERALD) { functions { setCount(32f) } } } } } ``` #### setLootTable Set a container's loot table: ```kotlin itemModifier("chest_loot") { setLootTable( LootTableType.CHEST, LootTables.Chests.SIMPLE_DUNGEON, seed = 12345L ) } ``` #### modifyContents Apply modifiers to items inside a container: ```kotlin itemModifier("enchant_bundle_contents") { modifyContents(ContentComponentTypes.BUNDLE_CONTENTS) { modifiers { enchantRandomly() } } } ``` ### Maps and Exploration #### explorationMap Convert empty map to explorer map: ```kotlin itemModifier("treasure_map") { explorationMap { destination = Tags.Worldgen.Structure.BURIED_TREASURE decoration = MapDecorationTypes.RED_X zoom = 2 searchRadius = 50 skipExistingChunks = true } } ``` ### Special Items #### setInstrument Set goat horn instrument: ```kotlin itemModifier("horn") { setInstrument(Tags.Instrument.GOAT_HORNS) } ``` #### setPotion Set potion type: ```kotlin itemModifier("potion") { setPotion(Potions.STRONG_HEALING) } ``` #### setStewEffect Set suspicious stew effects: ```kotlin itemModifier("stew") { setStewEffect { potionEffect(Effects.REGENERATION, duration = 100) potionEffect(Effects.SATURATION, duration = 200) } } ``` #### setFireworks Configure firework rocket: ```kotlin itemModifier("firework") { setFireworks(flightDuration = 2) { explosions { explosion(FireworkExplosionShape.LARGE_BALL) { colors(Color.RED, Color.ORANGE) fadeColors(Color.YELLOW) hasTrail = true hasTwinkle = true } } } } ``` #### setBookCover Set written book cover: ```kotlin itemModifier("book") { setBookCover( title = "Adventure Log", author = "Player", generation = 0 ) } ``` ### Attributes #### setAttributes Add attribute modifiers: ```kotlin itemModifier("buffed") { setAttributes { attribute( attribute = Attributes.ATTACK_DAMAGE, operation = AttributeModifierOperation.ADD_VALUE, amount = constant(5f), id = "bonus_damage", slot = EquipmentSlot.MAINHAND ) attribute( attribute = Attributes.MOVEMENT_SPEED, operation = AttributeModifierOperation.ADD_MULTIPLIED_BASE, amount = constant(0.1f), id = "speed_boost", slot = EquipmentSlot.FEET ) } } ``` ### Banners and Patterns #### setBannerPattern Add banner patterns: ```kotlin itemModifier("banner") { setBannerPattern(append = true) { pattern(BannerPatterns.STRIPE_TOP, DyeColors.RED) pattern(BannerPatterns.STRIPE_BOTTOM, DyeColors.BLUE) } } ``` ### Block State #### copyState Copy block state to item: ```kotlin itemModifier("block_state") { copyState(Blocks.FURNACE) { properties("facing", "lit") } } ``` ### Bonus Formulas #### applyBonus Apply enchantment-based bonus formulas: ```kotlin itemModifier("fortune") { // Ore drops formula applyBonus(Enchantments.FORTUNE) { formula = OreDrops() } // Uniform bonus applyBonus(Enchantments.FORTUNE) { formula = UniformBonusCount(bonusMultiplier = 1f) } // Binomial distribution applyBonus(Enchantments.FORTUNE) { formula = BinomialWithBonusCount(extra = 3, probability = 0.5f) } } ``` ### Smelting and Decay #### furnaceSmelt Smelt the item as if in a furnace: ```kotlin itemModifier("auto_smelt") { furnaceSmelt() } ``` #### explosionDecay Random chance to destroy items based on explosion: ```kotlin itemModifier("explosion") { explosionDecay() } ``` ### Player Heads #### fillPlayerHead Set player head skin: ```kotlin itemModifier("head") { fillPlayerHead(Source.KILLER) } ``` ### Tooltips #### toggleTooltips Show/hide tooltip sections: ```kotlin itemModifier("clean_tooltip") { toggleTooltips { enchantments = false modifiers = false canBreak = false canPlaceOn = false } } ``` ### Composition #### sequence Run multiple functions in sequence: ```kotlin itemModifier("complex") { sequence { setCount(1f) enchantRandomly() setName("Mystery Item") } } ``` #### filtered Apply functions only to matching items: ```kotlin itemModifier("filter") { filtered { itemFilter(Items.DIAMOND, Items.EMERALD) modifiers { setCount(uniform(1f, 5f)) } } } ``` #### reference Reference another item modifier: ```kotlin val baseModifier = itemModifier("base") { setCount(1f) } itemModifier("extended") { reference(baseModifier) enchantRandomly() } ``` ## Conditions Every function can have conditions that must pass: ```kotlin itemModifier("conditional") { setCount(10f) { conditions { // Multiple conditions are AND-ed killedByPlayer() randomChance(0.5f) } } enchantRandomly { conditions { weatherCheck(raining = true) } } } ``` See [Predicates](./predicates) for all available conditions. ## Full Example ```kotlin dataPack("legendary_items") { val legendaryModifier = itemModifier("legendary_weapon") { // High-level enchantments enchantWithLevels(levels = constant(30f)) { conditions { randomChance(0.3f) } } // Guaranteed enchantments setEnchantments { enchantment(Enchantments.UNBREAKING, 3) } // Custom name with formatting setName(textComponent("Legendary Weapon") { color = Color.GOLD bold = true }) // Lore setLore { lore("Forged in ancient flames", Color.GRAY) lore("", Color.WHITE) lore("▸ +5 Attack Damage", Color.GREEN) mode(Mode.REPLACE_ALL) } // Attributes setAttributes(replace = false) { attribute( attribute = Attributes.ATTACK_DAMAGE, operation = AttributeModifierOperation.ADD_VALUE, amount = constant(5f), id = "legendary_damage", slot = EquipmentSlot.MAINHAND ) } // Full durability setDamage(1.0f) } // Use in loot table lootTable("boss_weapon") { pool { rolls = constant(1f) entries { item(Items.DIAMOND_SWORD) { functions { reference(legendaryModifier) } } } } } // Use with command load { items { modify(self(), WEAPON.MAINHAND, legendaryModifier) } } } ``` ### Generated JSON ```json [ { "function": "minecraft:enchant_with_levels", "levels": 30.0, "conditions": [ { "condition": "minecraft:random_chance", "chance": 0.3 } ] }, { "function": "minecraft:set_enchantments", "enchantments": { "minecraft:unbreaking": 3 } }, { "function": "minecraft:set_name", "name": { "text": "Legendary Weapon", "color": "gold", "bold": true } }, { "function": "minecraft:set_lore", "lore": [ { "text": "Forged in ancient flames", "color": "gray" }, { "text": "" }, { "text": "▸ +5 Attack Damage", "color": "green" } ], "mode": "replace_all" }, { "function": "minecraft:set_attributes", "modifiers": [ { "attribute": "minecraft:attack_damage", "id": "minecraft:legendary_damage", "amount": 5.0, "operation": "add_value", "slot": "mainhand" } ], "replace": false }, { "function": "minecraft:set_damage", "damage": 1.0 } ] ``` ## Best Practices 1. **Keep modifiers focused** - Create small, reusable modifiers and compose with `reference()` 2. **Use conditions wisely** - Guard expensive operations with appropriate conditions 3. **Prefer components** - Use `setComponents` for direct component manipulation when possible 4. **Consider context** - Some functions require specific loot contexts (killer, tool, etc.) 5. **Test thoroughly** - Verify modifiers work in all intended contexts (loot, commands, etc.) ## See Also - [Predicates](./predicates) - Conditions for item functions - [Components](../concepts/components) - Understanding item components - [Loot Tables](./loot-tables) - Use item modifiers in loot tables - [Commands](../commands/commands) - Using the `/item` command ### External Resources - [Minecraft Wiki: Item modifier](https://minecraft.wiki/w/Item_modifier) - Official JSON format reference --- ## Loot Tables --- root: .components.layouts.MarkdownLayout title: Loot Tables nav-title: Loot Tables description: Create and customize Minecraft loot tables using Kore's type-safe Kotlin DSL for drops, container contents, fishing, and more. keywords: minecraft, datapack, kore, loot tables, pools, entries, item modifiers, drops date-created: 2025-08-11 date-modified: 2026-02-03 routeOverride: /docs/data-driven/loot-tables --- # Loot Tables Loot tables are JSON files that dictate what items should generate in various game situations. They control drops from mobs and blocks, contents of naturally generated containers (chests, barrels, dispensers), fishing rewards, archaeology brushing results, bartering exchanges, and more. ## Overview Loot tables have several key characteristics: - **Context-dependent**: Different loot contexts provide different parameters (killer entity, tool, luck level, etc.) - **Randomized**: Use number providers for rolls and weighted entries for varied results - **Conditional**: Apply predicates to pools, entries, and functions - **Composable**: Reference other loot tables as entries for modularity - **Transformable**: Apply item modifier functions to modify generated items ## File Structure Loot tables are stored as JSON files in data packs at: ``` data//loot_table/.json ``` For complete JSON specification, see the [Minecraft Wiki - Loot table](https://minecraft.wiki/w/Loot_table). ## Creating Loot Tables Use the `lootTable` builder function to create loot tables in Kore: ```kotlin dataPack("my_datapack") { lootTable("custom_chest") { pool { rolls = constant(3f) entries { item(Items.DIAMOND) { weight = 1 } item(Items.GOLD_INGOT) { weight = 5 } item(Items.IRON_INGOT) { weight = 10 } } } } } ``` This generates `data/my_datapack/loot_table/custom_chest.json`. ## Table Structure A loot table consists of: | Property | Type | Description | |------------------|--------------------------|-----------------------------------------------------| | `type` | `LootTableType` | Optional context type for validation | | `pools` | `List` | One or more pools that generate items | | `functions` | `ItemModifier` | Optional global item functions applied to all drops | | `randomSequence` | `RandomSequenceArgument` | Optional deterministic random sequence | ### Setting the Type The type validates that the loot table uses appropriate context parameters: ```kotlin lootTable("entity_drops") { type = LootTableType.ENTITY pool { // Entity context allows accessing killer, damage source, etc. } } ``` Available types: `ADVANCEMENT_ENTITY`, `ADVANCEMENT_LOCATION`, `ADVANCEMENT_REWARD`, `ARCHEOLOGY`, `BARTER`, `BLOCK`, `BLOCK_USE`, `CHEST`, `COMMAND`, `EMPTY`, `ENTITY`, `EQUIPMENT`, `FISHING`, `GIFT`, `GENERIC`, `SELECTOR`, `SHEARING`, `VAULT`. ### Global Functions Apply item modifier functions to all items dropped by the table: ```kotlin lootTable("enchanted_loot") { functions { enchantRandomly { options += Enchantments.LOOTING } } pool { entries { item(Items.DIAMOND_SWORD) } } } ``` ## Pools Each pool represents an independent set of rolls. A table can have multiple pools that all contribute to the final loot. ### Pool Properties | Property | Type | Description | |--------------|-------------------|------------------------------------------------| | `rolls` | `NumberProvider` | How many times to select from entries | | `bonusRolls` | `NumberProvider` | Additional rolls per luck level | | `conditions` | `Predicate` | Conditions that must pass for pool to activate | | `entries` | `List` | Possible entries to select from | | `functions` | `ItemModifier` | Functions applied to items from this pool | ### Basic Pool ```kotlin lootTable("simple_pool") { pool { rolls = constant(2f) bonusRolls = constant(1f) entries { item(Items.EMERALD) } } } ``` ### Conditional Pool ```kotlin lootTable("weather_dependent") { pool { rolls = constant(1f) conditions { weatherCheck(raining = true) } entries { item(Items.WATER_BUCKET) } } } ``` ### Pool with Functions ```kotlin lootTable("modified_drops") { pool { rolls = constant(1f) entries { item(Items.DIAMOND_PICKAXE) } functions { setDamage(0.5f) enchantWithLevels(levels = constant(30f)) } } } ``` ## Number Providers Number providers determine dynamic numeric values for rolls, counts, and other quantities. | Provider | Description | Example | |-------------------------|----------------------------|-----------------------------------------| | `constant(value)` | Fixed value | `constant(5f)` | | `uniform(min, max)` | Random between min and max | `uniform(1f, 5f)` | | `binomial(n, p)` | Binomial distribution | `binomial(5, 0.5f)` | | `scoreNumber(...)` | Value from scoreboard | `scoreNumber("kills", EntityType.THIS)` | | `enchantmentLevel(...)` | Based on enchantment level | `enchantmentLevel(5)` | ```kotlin pool { rolls = uniform(2f, 5f) // 2-5 rolls randomly bonusRolls = constant(1f) // +1 roll per luck level entries { item(Items.GOLD_INGOT) } } ``` ## Entries Entries define what can be selected during a pool roll. There are singleton entries (yield items) and composite entries (combine other entries). ### Singleton Entries #### Item Entry Drops a specific item: ```kotlin entries { item(Items.DIAMOND) { weight = 1 quality = 2 conditions { randomChance(0.5f) } functions { setCount(uniform(1f, 3f)) } } } ``` #### Loot Table Entry References another loot table: ```kotlin entries { lootTable(LootTables.Gameplay.PIGLIN_BARTERING) { weight = 1 functions { setCount(2f) } } } ``` #### Tag Entry Drops items from an item tag: ```kotlin entries { tag(Tags.Item.ARROWS) { expand = true // Each item becomes a separate entry weight = 1 } } ``` #### Dynamic Entry For block-specific drops (shulker box contents, decorated pot sherds): ```kotlin entries { dynamic("contents") { // Drops contents of shulker boxes } } ``` #### Empty Entry A weighted entry that drops nothing (useful for rarity): ```kotlin entries { empty { weight = 10 // 10x more likely than weight=1 entries } } ``` ### Composite Entries #### Alternatives Selects the first entry whose conditions pass: ```kotlin entries { alternatives { children { item(Items.DIAMOND) { conditions { randomChance(0.1f) } } item(Items.GOLD_INGOT) { conditions { randomChance(0.3f) } } item(Items.IRON_INGOT) // Fallback } } } ``` #### Group All children are added to the pool if conditions pass: ```kotlin entries { group { conditions { weatherCheck(raining = true) } children { item(Items.WATER_BUCKET) item(Items.FISH) } } } ``` #### Sequence Children are added until one fails its conditions: ```kotlin entries { sequence { children { item(Items.DIAMOND) { conditions { randomChance(0.5f) } } item(Items.EMERALD) { conditions { randomChance(0.5f) } } item(Items.GOLD_INGOT) } } } ``` ### Entry Properties Singleton entries share these properties: | Property | Type | Description | |--------------|----------------|----------------------------------------------------------| | `weight` | `Int` | Selection weight (higher = more likely) | | `quality` | `Int` | Modifies weight based on luck: `weight + quality × luck` | | `conditions` | `Predicate` | Entry only available if conditions pass | | `functions` | `ItemModifier` | Functions applied to this entry's items | ## Conditions (Predicates) Conditions control when pools, entries, or functions apply. They use the same Predicate system as advancements. ```kotlin pool { conditions { // Multiple conditions are AND-ed weatherCheck(raining = true) randomChance(0.5f) // Check entity properties entityProperties { type(EntityTypes.PLAYER) } // Check killer killedByPlayer() // Check tool matchTool { items = listOf(Items.DIAMOND_PICKAXE) } } } ``` See [Predicates](./predicates) for the complete list of available conditions. ## Functions (Item Modifiers) Functions transform the generated items. They can be applied at table, pool, or entry level. ### Common Functions ```kotlin functions { // Set stack count setCount(uniform(1f, 5f)) // Apply enchantments enchantRandomly { options += Enchantments.FORTUNE } // Set damage (durability) setDamage(0.8f) // Add custom name setName("Legendary Sword") // Conditional function setCount(10f) { conditions { killedByPlayer() } } } ``` See [Item Modifiers](./item-modifiers) for the complete list of available functions. ## Full Example ```kotlin dataPack("treasure_hunt") { // Custom boss drop table lootTable("boss_drops") { type = LootTableType.ENTITY // Global enchantment on all drops functions { enchantRandomly() } // Guaranteed drops pool { rolls = constant(1f) entries { item(Items.NETHER_STAR) } } // Rare equipment drops pool { rolls = constant(1f) bonusRolls = constant(0.5f) conditions { killedByPlayer() } entries { item(Items.NETHERITE_SWORD) { weight = 1 functions { enchantWithLevels(levels = constant(30f)) setName("Boss Slayer") } } item(Items.DIAMOND_SWORD) { weight = 5 functions { enchantWithLevels(levels = uniform(15f, 25f)) } } empty { weight = 10 } } } // Bonus loot from existing table pool { rolls = uniform(1f, 3f) entries { lootTable(LootTables.Chests.END_CITY_TREASURE) } } } } ``` ### Generated JSON ```json { "type": "minecraft:entity", "functions": [ { "function": "minecraft:enchant_randomly" } ], "pools": [ { "rolls": 1.0, "entries": [ { "type": "minecraft:item", "name": "minecraft:nether_star" } ] }, { "rolls": 1.0, "bonus_rolls": 0.5, "conditions": [ { "condition": "minecraft:killed_by_player" } ], "entries": [ { "type": "minecraft:item", "name": "minecraft:netherite_sword", "weight": 1, "functions": [ { "function": "minecraft:enchant_with_levels", "levels": 30.0 }, { "function": "minecraft:set_name", "name": "Boss Slayer" } ] }, { "type": "minecraft:item", "name": "minecraft:diamond_sword", "weight": 5, "functions": [ { "function": "minecraft:enchant_with_levels", "levels": { "type": "minecraft:uniform", "min": 15.0, "max": 25.0 } } ] }, { "type": "minecraft:empty", "weight": 10 } ] }, { "rolls": { "type": "minecraft:uniform", "min": 1.0, "max": 3.0 }, "entries": [ { "type": "minecraft:loot_table", "name": "minecraft:chests/end_city_treasure" } ] } ] } ``` ## Using with Commands Spawn loot from a table using the `/loot` command: ```kotlin load { // Give loot directly to player loot(self(), myLootTable) // Spawn loot at position loot(vec3(0, 64, 0), myLootTable) // Insert loot into container loot(block(0, 64, 0), myLootTable) } ``` ## Overriding Vanilla Tables To modify vanilla loot tables, create a file with the same path in your datapack: ```kotlin dataPack("better_zombies") { // This overrides minecraft:entities/zombie lootTable("entities/zombie") { namespace = "minecraft" pool { rolls = constant(1f) entries { item(Items.ROTTEN_FLESH) { functions { setCount(uniform(0f, 2f)) lootingEnchant(uniform(0f, 1f)) } } } } // Add custom drops pool { rolls = constant(1f) conditions { randomChance(0.1f) } entries { item(Items.DIAMOND) } } } } ``` ## Best Practices 1. **Use appropriate types** - Set the `type` field to catch invalid context parameter usage early 2. **Organize with multiple pools** - Use separate pools for different drop categories (guaranteed, rare, conditional) 3. **Leverage composition** - Reference other loot tables instead of duplicating entries 4. **Weight appropriately** - Use meaningful weights (e.g., 1/5/10/50) for clear rarity tiers 5. **Apply conditions at the right level** - Pool conditions for entire categories, entry conditions for specific items ## See Also - [Predicates](./predicates) - Conditions used in loot table pools and entries - [Item Modifiers](./item-modifiers) - Functions applied to loot table items - [Advancements](./advancements) - Rewards can reference loot tables - [Commands](../commands/commands) - Using the `/loot` command - [Tags](./tags) - Use item tags for tag entries ### External Resources - [Minecraft Wiki: Loot table](https://minecraft.wiki/w/Loot_table) - Official JSON format reference - [Minecraft Wiki: Loot context](https://minecraft.wiki/w/Loot_context) - Understanding loot contexts --- ## Predicates --- root: .components.layouts.MarkdownLayout title: Predicates nav-title: Predicates description: Learn how to use predicates in your Kore datapacks keywords: minecraft, datapack, kore, predicates, conditions, entity properties date-created: 2024-01-08 date-modified: 2026-02-03 routeOverride: /docs/data-driven/predicates --- # Predicates Predicates are JSON structures used in data packs to check conditions within the world. They return a pass or fail result to the invoker, which acts differently based on the result. In practical terms, predicates are a flexible way for data packs to encode "if this, then that" logic without needing custom code. Predicates can be used in: - **Commands**: Via `/execute if predicate` or target selector argument `predicate=` - **Loot tables**: As conditions for loot entries - **Advancements**: As trigger conditions - **Other predicates**: Via the `reference` condition Kore provides a type-safe DSL to create predicates, eliminating the need to write raw JSON. ## Basic Usage Here's a simple example of creating a predicate that checks if a player is holding a diamond pickaxe: ```kotlin val myPredicate = predicate("test") { matchTool { item(Items.DIAMOND_PICKAXE) } } ``` The `predicate` function creates and registers a predicate in your DataPack. It produces a file at `data//predicate/.json` and returns a `PredicateArgument` that can be used in commands. ## Conditions Predicates can have multiple conditions that must be met. You can combine them using `allOf` or `anyOf`: ```kotlin predicate("complex_test") { allOf { enchantmentActiveCheck(true) randomChance(0.5f) randomChanceWithEnchantedBonus( unenchantedChance = 3f, enchantedChance = 2, Enchantments.EFFICIENCY ) weatherCheck(raining = true, thundering = false) } } ``` You can also use the `inverted` condition to invert the result of a predicate: ```kotlin predicate("inverted_test") { inverted { randomChance(0.5f) } } ``` ### Available Conditions Conditions are categorized by their **loot context requirements **. Some conditions can be invoked from any context, while others require specific data to be available. #### Universal Conditions (invokable from any context) | Condition | Description | |--------------------|------------------------------------------------------------------------------------| | `allOf` | Evaluates a list of predicates and passes if **all** of them pass | | `anyOf` | Evaluates a list of predicates and passes if **any one** of them passes | | `entityProperties` | Checks properties of an entity | | `inverted` | Inverts another predicate condition | | `randomChance` | Generates a random number between 0.0 and 1.0, passes if less than specified value | | `reference` | Invokes another predicate file and returns its result (cannot be cyclic) | | `timeCheck` | Compares the current day time against given values (supports `period` for modulo) | | `valueCheck` | Compares a number against another number or range | | `weatherCheck` | Checks the current game weather (raining, thundering) | #### Context-Dependent Conditions These conditions require specific loot context data and will **always fail** if that data is not provided: | Condition | Required Context | Description | |----------------------------------|-----------------------------|---------------------------------------------------------------------------------------| | `blockStateProperty` | Block state | Checks the mined block and its block states | | `damageSourceProperties` | Origin + damage source | Checks properties of the damage source | | `enchantmentActiveCheck` | Enchantment active status | Checks if an enchantment is active (only usable from `enchanted_location` context) | | `entityScores` | Specified entity | Checks the scoreboard scores of an entity | | `killedByPlayer` | `attacking_player` entity | Checks if there is an attacking player entity | | `locationCheck` | Origin | Checks the current location against location criteria (supports offsets) | | `matchTool` | Tool | Checks tool used to mine the block | | `randomChanceWithEnchantedBonus` | Attacker entity (optional) | Random chance modified by enchantment level (level 0 if no attacker) | | `survivesExplosion` | Explosion radius (optional) | Returns success with 1 ÷ explosion radius probability (always passes if no explosion) | | `tableBonus` | Tool (optional) | Passes with probability from a list indexed by enchantment power (level 0 if no tool) | ## Entity Properties The `entityProperties` condition allows you to check various properties of an entity. You must specify which entity to check using the `entity` parameter: ### Entity Context Options | Value | Description | |----------------------|-----------------------------------------------------------| | `this` | The entity that invoked the predicate (default) | | `attacker` | The entity that attacked | | `direct_attacker` | The direct cause of damage (e.g., arrow, not the shooter) | | `attacking_player` | The attacking player specifically | | `target_entity` | The targeted entity | | `interacting_entity` | The entity interacting with something | ### Entity Predicate Example ```kotlin predicate("entity_check") { entityProperties { // Check entity components (e.g., axolotl variant) components { axolotlVariant(AxolotlVariants.CYAN) damage(12) !unbreakable() // Negated component check } // Check effects effects { this[Effects.INVISIBILITY] = effect { amplifier = rangeOrInt(1) } } // Check equipment equipment { mainHand = itemStack(Items.DIAMOND_SWORD) } // Check entity flags flags { isBaby = true } // Check location location { block { blocks(Blocks.STONE) } } // Check movement movement { x(1.0, 4.0) horizontalSpeed(1.0) } // Check what affects entity movement movementAffectedBy { canSeeSky = true } // Check NBT data nbt { this["foo"] = "bar" } // Check entity passenger passenger { team = "foo" } // Check custom data predicates predicates { customData { this["foo"] = "bar" } } // Check specific inventory slots slots { this[WEAPON.MAINHAND] = itemStack(Items.DIAMOND_SWORD) } // Check block the entity is standing on steppingOn { blocks(Blocks.STONE) components { damage(5) } predicates { customData { this["foo"] = "bar" } } state("up", "bottom") } // Check entity type type(EntityTypes.MARKER) // Check player-specific properties playerTypeSpecific { gamemodes(Gamemode.SURVIVAL) } // Check entity vehicle with distance vehicle { distance { x(1f..4f) z(1f) } } } } ``` ## Sub-Predicates Sub-predicates are nested data structures that allow you to define specific properties to check within a predicate condition. Each condition type can have its own set of sub-predicates. ### Entity Sub-Predicates The `entityProperties` condition supports various sub-predicates to check different aspects of an entity: | Sub-Predicate | Description | Example | |----------------------|------------------------------------------|--------------------------------------------------------------------------| | `components` | Check entity data components | `components { axolotlVariant(AxolotlVariants.CYAN) }` | | `distance` | Check distance between entities | `distance { x(1f..4f) }` | | `effects` | Check potion effects | `effects { this[Effects.SPEED] = effect { amplifier = rangeOrInt(1) } }` | | `equipment` | Check equipped items | `equipment { mainHand = itemStack(Items.DIAMOND_SWORD) }` | | `flags` | Check entity flags (baby, on fire, etc.) | `flags { isBaby = true }` | | `location` | Check entity location | `location { block { blocks(Blocks.STONE) } }` | | `movement` | Check entity movement | `movement { x(1.0, 4.0); horizontalSpeed(1.0) }` | | `movementAffectedBy` | Check what affects entity movement | `movementAffectedBy { canSeeSky = true }` | | `nbt` | Check entity NBT data | `nbt { this["foo"] = "bar" }` | | `passenger` | Check entity passenger | `passenger { team = "foo" }` | | `periodicTicks` | Check entity periodic ticks | `periodicTicks = 20` | | `predicates` | Check custom data predicates | `predicates { customData { this["key"] = "value" } }` | | `slots` | Check specific inventory slots | `slots { this[WEAPON.MAINHAND] = itemStack(Items.DIAMOND_SWORD) }` | | `steppingOn` | Check block the entity is standing on | `steppingOn { blocks(Blocks.STONE) }` | | `targetedEntity` | Check entity being targeted | `targetedEntity { type(EntityTypes.ZOMBIE) }` | | `team` | Check entity team | `team = "my_team"` | | `type` | Check entity type | `type(EntityTypes.MARKER)` | | `typeSpecific` | Check type-specific properties | See [Type-Specific Properties](#entity-type-specific-properties) | | `vehicle` | Check entity vehicle | `vehicle { distance { x(1f..4f) } }` | The `Entity` class provides all the functions for these sub-predicates. ### Entity Type-Specific Properties Entities can still expose a handful of hard-coded type-specific predicates (mainly utility ones such as fishing hooks, lightning, player, raider, sheep and slime). All the visual *variant* checks that existed before snapshot **25w04a** were migrated by Mojang to the new **components ** system. Kore therefore removed the dedicated helpers (`axolotlTypeSpecific`, `catTypeSpecific`, …) in favor of component matching. #### Component-based variant checks (25w04a +) You can now query an entity’s data components directly from `entityProperties` with the `components` block: ```kotlin // Check axolotl variant via its component predicate("axolotl_component_check") { entityProperties { components { axolotlVariant(AxolotlVariants.LUCY) } } } ``` Any component you can put on an **item** can be matched on an **entity ** in exactly the same way – just call the corresponding extension inside the `components {}` scope. #### Remaining built-in `typeSpecific` helpers These helpers are still available because they cover information that is **not** represented by components: ##### Fishing Hook Check if a fishing hook is in open water: ```kotlin predicate("fishing_hook_check") { entityProperties { fishingHookTypeSpecific(inOpenWater = true) } } ``` ##### Lightning Check lightning bolt properties like blocks set on fire: ```kotlin predicate("lightning_check") { entityProperties { lightningTypeSpecific { blocksSetOnFire = rangeOrInt(1..5) } } } ``` ##### Player Check player-specific properties including gamemode, unlocked recipes, and input state: ```kotlin predicate("player_check") { entityProperties { playerTypeSpecific { gamemodes(Gamemode.CREATIVE) recipes { this[Recipes.BOW] = true } input { forward = true backward = false left = true right = false jump = true sneak = false sprint = true } } } } ``` ##### Raider Check raider properties like raid participation and captain status: ```kotlin predicate("raider_check") { entityProperties { raiderTypeSpecific(hasRaid = true, isCaptain = false) } } ``` ##### Sheep Check if a sheep has been sheared: ```kotlin predicate("sheep_check") { entityProperties { sheepTypeSpecific(sheared = true) } } ``` ##### Slime Check slime size: ```kotlin predicate("slime_check") { entityProperties { slimeTypeSpecific(rangeOrInt(2)) } } ``` > **Note** All former `*TypeSpecific` helpers that dealt with variants (axolotl, cat, fox, frog, horse, llama, mooshroom, painting, parrot, pig, rabbit, salmon, tropical fish, villager, wolf) have been removed. Update your predicates to use component matching instead. ### Item Sub-Predicates When using `matchTool` or checking equipment, you can use item sub-predicates. There are two main ways to check item properties: 1. Basic item properties: ```kotlin predicate("basic_item_check") { matchTool { item(Items.DIAMOND_SWORD) count = rangeOrInt(1..64) durability = rangeOrInt(0..100) } } ``` 2. Component Matchers - A powerful system to check component properties: ```kotlin predicate("component_check") { matchTool { item(Items.DIAMOND_SWORD) predicates { // Check damage and durability damage { durability(1) damage = rangeOrInt(4..5) } // Check enchantments enchantments { enchantment(Enchantments.SHARPNESS, level = 3) } } } } ``` Component Matchers allow you to check various item components like: - Attribute modifiers - Container contents (bundles, shulker boxes) - Damage and durability - Enchantments - Firework properties - Book contents - And many more Each matcher corresponds to a component type in Minecraft and provides type-safe ways to check their properties. For a complete list of available matchers, refer to the `arguments.components.matchers` package in the source code. ## Using Predicates in Commands Predicates can be invoked in commands in two ways: ### Execute If Predicate Use `/execute if predicate` to conditionally run commands: ```kotlin function("test") { execute { ifCondition { predicate(myPredicate) } run { debug("predicate validated!") } } } ``` ### Target Selector Argument Use the `predicate=` selector argument to filter entities: ```kotlin function("filter_entities") { // Kill all entities matching the predicate kill(allEntities { predicate = myPredicate }) } ``` ### Pairing with Inventory Manager Predicates excel at validating complex item properties. When you need to both validate and actively manage inventories (e.g., keep a GUI slot populated with an item matching specific components), use them alongside the [Inventory Manager](./helpers/inventory-manager). ## Item Predicates You can also create predicates for items with enchantments: ```kotlin predicate("enchanted_tool") { matchTool { item(Items.DIAMOND_PICKAXE) predicates { enchantments(enchantment(Enchantments.EFFICIENCY)) } } } ``` ## Referencing Other Predicates Use the `reference` condition to invoke another predicate file: ```kotlin val basePredicate = predicate("base_check") { weatherCheck(raining = true) } predicate("combined_check") { allOf { reference(basePredicate) randomChance(0.5f) } } ``` > **Warning**: Cyclic references (predicate A references B, which references A) will cause a parsing failure. ## Best Practices 1. **Descriptive names**: Give your predicates names that reflect their purpose (e.g., `is_holding_sword`, `in_rain_at_night`) 2. **Logical composition**: Use `allOf` and `anyOf` to combine multiple conditions clearly 3. **Reusability**: Keep predicates focused on a single concern and use `reference` to compose them 4. **Context awareness **: Be mindful of which loot context your predicate will be invoked from. Context-dependent conditions will silently fail if required data is missing 5. **Testing**: Test your predicates in-game using `/execute if predicate ` to verify they work as expected Predicates are powerful tools for creating complex conditions in your datapack. They enable sophisticated game mechanics and enhance player experience without requiring custom code. ## See Also - [Loot Tables](./loot-tables) - Use predicates as conditions for loot entries - [Advancements](./advancements) - Use predicates as trigger conditions - [Item Modifiers](./item-modifiers) - Modify items conditionally with predicates - [Components](../concepts/components) - Item and entity data components used in predicate checks - [Commands](../commands/commands) - Using predicates with `/execute if predicate` - [Inventory Manager](./helpers/inventory-manager) - Pair predicates with inventory management - [Tags](./tags) - Use tags in predicate conditions ### External Resources - [Minecraft Wiki: Predicate](https://minecraft.wiki/w/Predicate) - Official JSON format reference - [Minecraft Wiki: Loot context](https://minecraft.wiki/w/Loot_context) - Understanding loot contexts for conditions --- ## Recipes --- root: .components.layouts.MarkdownLayout title: Recipes nav-title: Recipes description: Create custom Minecraft recipes using Kore's type-safe Kotlin DSL for crafting, smelting, smithing, and more. keywords: minecraft, datapack, kore, recipes, crafting, smelting, smithing, stonecutting date-created: 2024-01-08 date-modified: 2026-02-03 routeOverride: /docs/data-driven/recipes --- # Recipes Recipes define how items are transformed through crafting tables, furnaces, smithing tables, stonecutters, and other workstations. Kore provides a type-safe DSL to create all vanilla recipe types programmatically. ## Overview Recipes have several key characteristics: - **Type-specific**: Each workstation has its own recipe format - **Discoverable**: Recipes can be unlocked via advancements - **Customizable results**: Output items can have custom components - **Tag-based ingredients**: Use item tags for flexible ingredient matching ### Recipe Types | Type | Workstation | Description | |----------------------|----------------|------------------------------| | `crafting_shaped` | Crafting Table | Pattern-based crafting | | `crafting_shapeless` | Crafting Table | Order-independent crafting | | `crafting_transmute` | Crafting Table | Transform item with material | | `crafting_special_*` | Crafting Table | Built-in special recipes | | `smelting` | Furnace | Standard smelting | | `blasting` | Blast Furnace | Faster ore smelting | | `smoking` | Smoker | Faster food cooking | | `campfire_cooking` | Campfire | Slow food cooking | | `smithing_transform` | Smithing Table | Upgrade items | | `smithing_trim` | Smithing Table | Apply armor trims | | `stonecutting` | Stonecutter | Cut blocks | ## File Structure Recipes are stored as JSON files in data packs at: ``` data//recipe/.json ``` For complete JSON specification, see the [Minecraft Wiki - Recipe](https://minecraft.wiki/w/Recipe). ## Creating Recipes Use the `recipes` block inside a data pack to define recipes: ```kotlin dataPack("my_datapack") { recipes { craftingShaped("diamond_sword_upgrade") { pattern( " E ", " D ", " S " ) keys { "E" to Items.EMERALD "D" to Items.DIAMOND_SWORD "S" to Items.STICK } result(Items.DIAMOND_SWORD) { enchantments { enchantment(Enchantments.SHARPNESS, 5) } } } } } ``` This generates `data/my_datapack/recipe/diamond_sword_upgrade.json`. ## Crafting Recipes ### Shaped Crafting Pattern-based recipes where ingredient positions matter: ```kotlin recipes { craftingShaped("my_pickaxe") { // Define the pattern (up to 3x3) pattern( "DDD", " S ", " S " ) // Map characters to items key("D", Items.DIAMOND) key("S", Items.STICK) // Or use keys block keys { "D" to Items.DIAMOND "S" to Items.STICK } // Set the result result(Items.DIAMOND_PICKAXE) // Optional: set category for recipe book category = CraftingCategory.EQUIPMENT } } ``` #### Pattern Rules - Patterns can be 1x1 to 3x3 - Use space ` ` for empty slots - Each character must be mapped in `key()` or `keys {}` - Patterns are automatically trimmed (no need for padding) ```kotlin // 2x2 recipe craftingShaped("torch") { pattern( "C", "S" ) keys { "C" to Items.COAL "S" to Items.STICK } result(Items.TORCH) count = 4 } // Using tags as ingredients craftingShaped("planks") { pattern("L") key("L", Tags.Item.LOGS) result(Items.OAK_PLANKS) count = 4 } ``` ### Shapeless Crafting Order-independent recipes: ```kotlin recipes { craftingShapeless("mushroom_stew") { ingredient(Items.BOWL) ingredient(Items.BROWN_MUSHROOM) ingredient(Items.RED_MUSHROOM) result(Items.MUSHROOM_STEW) } } ``` #### Multiple of Same Ingredient ```kotlin craftingShapeless("book") { ingredient(Items.PAPER) ingredient(Items.PAPER) ingredient(Items.PAPER) ingredient(Items.LEATHER) result(Items.BOOK) } ``` #### Using Tags ```kotlin craftingShapeless("dye_mix") { ingredient(Tags.Item.DYES) ingredient(Tags.Item.DYES) result(Items.MAGENTA_DYE) count = 2 } ``` ### Transmute Crafting Transform an item while preserving its components: ```kotlin recipes { craftingTransmute("dye_shulker") { input(Tags.Item.SHULKER_BOXES) material(Items.BLUE_DYE) result(Items.BLUE_SHULKER_BOX) } } ``` The result item copies all components from the input item. ### Special Crafting Special recipes use built-in game logic for complex crafting that can't be data-driven: ```kotlin recipes { craftingSpecial("armor_dye", CraftingSpecialArmorDye) craftingSpecial("banner_copy", CraftingSpecialBannerDuplicate) craftingSpecial("book_clone", CraftingSpecialBookCloning) craftingSpecial("firework_rocket", CraftingSpecialFireworkRocket) craftingSpecial("firework_star", CraftingSpecialFireworkStar) craftingSpecial("map_clone", CraftingSpecialMapCloning) craftingSpecial("map_extend", CraftingSpecialMapExtending) craftingSpecial("repair", CraftingSpecialRepairItem) craftingSpecial("shield_decor", CraftingSpecialShieldDecoration) craftingSpecial("shulker_color", CraftingSpecialShulkerboxColoring) craftingSpecial("tipped_arrow", CraftingSpecialTippedArrow) craftingSpecial("suspicious_stew", CraftingSpecialSuspiciousStew) } ``` These are useful when the vanilla datapack is disabled and you need to re-enable specific special recipes. ## Cooking Recipes All cooking recipes share a similar structure: | Property | Description | |---------------|-----------------------------------| | `ingredient` | Input item or tag | | `result` | Output item | | `experience` | XP awarded when collecting output | | `cookingTime` | Time in ticks | ### Smelting (Furnace) ```kotlin recipes { smelting("iron_ingot") { ingredient(Items.RAW_IRON) result(Items.IRON_INGOT) experience = 0.7 cookingTime = 200 // 10 seconds (default) } // Using tags smelting("glass") { ingredient(Tags.Item.SMELTS_TO_GLASS) result(Items.GLASS) experience = 0.1 } } ``` ### Blasting (Blast Furnace) Twice as fast as smelting (100 ticks default): ```kotlin recipes { blasting("iron_ingot_fast") { ingredient(Items.RAW_IRON) result(Items.IRON_INGOT) experience = 0.7 cookingTime = 100 // 5 seconds (default) } } ``` ### Smoking (Smoker) For food items, twice as fast as furnace: ```kotlin recipes { smoking("cooked_beef") { ingredient(Items.BEEF) result(Items.COOKED_BEEF) experience = 0.35 cookingTime = 100 } } ``` ### Campfire Cooking Slow cooking without fuel: ```kotlin recipes { campfireCooking("baked_potato") { ingredient(Items.POTATO) result(Items.BAKED_POTATO) experience = 0.35 cookingTime = 600 // 30 seconds (default) } } ``` ## Smithing Recipes ### Smithing Transform Upgrade items at the smithing table: ```kotlin recipes { smithingTransform("netherite_sword") { template(Items.NETHERITE_UPGRADE_SMITHING_TEMPLATE) base(Items.DIAMOND_SWORD) addition(Items.NETHERITE_INGOT) result(Items.NETHERITE_SWORD) } } ``` The result item copies components from the base item. #### Multiple Addition Options ```kotlin smithingTransform("custom_upgrade") { template(Items.NETHERITE_UPGRADE_SMITHING_TEMPLATE) base(Items.DIAMOND_SWORD) addition(Items.NETHERITE_INGOT, Items.NETHERITE_SCRAP) // Either works result(Items.NETHERITE_SWORD) } ``` ### Smithing Trim Apply armor trims: ```kotlin recipes { smithingTrim("sentry_trim") { template(Items.SENTRY_ARMOR_TRIM_SMITHING_TEMPLATE) base(Tags.Item.TRIMMABLE_ARMOR) addition(Tags.Item.TRIM_MATERIALS) pattern = TrimPatterns.SENTRY } } ``` ## Stonecutting Single-item recipes for the stonecutter: ```kotlin recipes { stoneCutting("stone_slab") { ingredient(Items.STONE) result(Items.STONE_SLAB) count = 2 } stoneCutting("stone_stairs") { ingredient(Items.STONE) result(Items.STONE_STAIRS) } // Multiple outputs from same ingredient (separate recipes) stoneCutting("stone_bricks") { ingredient(Items.STONE) result(Items.STONE_BRICKS) } } ``` ## Result Items with Components Add custom components to recipe results: ```kotlin recipes { craftingShaped("enchanted_book") { pattern( "E E", " B ", "E E" ) keys { "E" to Items.EMERALD "B" to Items.BOOK } result(Items.ENCHANTED_BOOK) { enchantments { enchantment(Enchantments.SHARPNESS, 5) } } } craftingShaped("damaged_sword") { pattern( " D", " D", " S" ) keys { "D" to Items.DAMAGED_DIAMOND "S" to Items.STICK } result(Items.DIAMOND_SWORD) { damage(100) // Partially damaged } } craftingShapeless("named_diamond") { ingredient(Items.DIAMOND) ingredient(Items.PAPER) result(Items.DIAMOND) { customName(textComponent("Certified Diamond", Color.AQUA)) lore(textComponent("100% Genuine", Color.GRAY)) } } } ``` ## Recipe Categories Organize recipes in the recipe book: ```kotlin craftingShaped("tool") { // ... pattern and keys result(Items.DIAMOND_PICKAXE) category = CraftingCategory.EQUIPMENT } smelting("food") { // ... ingredient and result category = SmeltingCategory.FOOD } ``` ### Crafting Categories - `BUILDING` - Building blocks - `REDSTONE` - Redstone components - `EQUIPMENT` - Tools, weapons, armor - `MISC` - Everything else ### Cooking Categories - `FOOD` - Food items - `BLOCKS` - Block transformations (sand → glass) - `MISC` - Everything else ## Recipe Groups Group similar recipes in the recipe book: ```kotlin recipes { craftingShaped("oak_planks") { pattern("L") key("L", Items.OAK_LOG) result(Items.OAK_PLANKS) count = 4 group = "planks" } craftingShaped("birch_planks") { pattern("L") key("L", Items.BIRCH_LOG) result(Items.BIRCH_PLANKS) count = 4 group = "planks" } } ``` Recipes with the same group appear together in the recipe book. ## Using Recipes in Commands ### Reference Recipes Store a recipe reference for use in commands: ```kotlin val myRecipe = recipesBuilder.craftingShaped("special_item") { pattern( " G ", "GBG", " G " ) keys { "G" to Items.GOLD_BLOCK "B" to Items.DIAMOND_BLOCK } result(Items.BEACON) } load { // Give recipe to all players recipeGive(allPlayers(), myRecipe) } ``` ### Give/Take Recipes ```kotlin load { // Give specific recipe recipeGive(self(), myRecipe) // Take recipe recipeTake(self(), myRecipe) // Give all recipes recipeGive(allPlayers(), "*") } ``` ## Overriding Vanilla Recipes Override vanilla recipes by using the minecraft namespace: ```kotlin dataPack("better_recipes") { recipes { // Override vanilla diamond sword recipe craftingShaped("diamond_sword") { namespace = "minecraft" pattern( " D ", " D ", " S " ) keys { "D" to Items.DIAMOND "S" to Items.STICK } result(Items.DIAMOND_SWORD) { enchantments { enchantment(Enchantments.UNBREAKING, 1) } } } } } ``` ## Full Example ```kotlin dataPack("custom_recipes") { recipes { // Shaped crafting with components craftingShaped("legendary_sword") { pattern( " N ", " N ", " B " ) keys { "N" to Items.NETHERITE_INGOT "B" to Items.BLAZE_ROD } result(Items.NETHERITE_SWORD) { customName(textComponent("Blade of Flames", Color.GOLD)) enchantments { enchantment(Enchantments.FIRE_ASPECT, 2) enchantment(Enchantments.SHARPNESS, 5) } unbreakable() } category = CraftingCategory.EQUIPMENT } // Shapeless recipe craftingShapeless("quick_tnt") { ingredient(Items.GUNPOWDER) ingredient(Items.GUNPOWDER) ingredient(Items.GUNPOWDER) ingredient(Items.GUNPOWDER) ingredient(Tags.Item.SAND) result(Items.TNT) } // Transmute recipe craftingTransmute("repaint_bed") { input(Tags.Item.BEDS) material(Items.WHITE_DYE) result(Items.WHITE_BED) } // Smelting with experience smelting("ancient_debris") { ingredient(Items.ANCIENT_DEBRIS) result(Items.NETHERITE_SCRAP) experience = 2.0 cookingTime = 200 category = SmeltingCategory.MISC } // Smithing upgrade smithingTransform("netherite_boots") { template(Items.NETHERITE_UPGRADE_SMITHING_TEMPLATE) base(Items.DIAMOND_BOOTS) addition(Items.NETHERITE_INGOT) result(Items.NETHERITE_BOOTS) } // Smithing trim smithingTrim("ward_trim") { template(Items.WARD_ARMOR_TRIM_SMITHING_TEMPLATE) base(Tags.Item.TRIMMABLE_ARMOR) addition(Tags.Item.TRIM_MATERIALS) pattern = TrimPatterns.WARD } // Stonecutting variants stoneCutting("cut_copper_slab") { ingredient(Items.COPPER_BLOCK) result(Items.CUT_COPPER_SLAB) count = 8 } } // Reference recipe in function val beaconRecipe = recipesBuilder.craftingShaped("easy_beacon") { pattern( "GGG", "GSG", "OOO" ) keys { "G" to Items.GLASS "S" to Items.NETHER_STAR "O" to Items.OBSIDIAN } result(Items.BEACON) } load { recipeGive(allPlayers(), beaconRecipe) } } ``` ### Generated JSON (Shaped Recipe) ```json { "type": "minecraft:crafting_shaped", "category": "equipment", "pattern": [ " N ", " N ", " B " ], "key": { "N": "minecraft:netherite_ingot", "B": "minecraft:blaze_rod" }, "result": { "id": "minecraft:netherite_sword", "components": { "custom_name": { "text": "Blade of Flames", "color": "gold" }, "enchantments": { "minecraft:fire_aspect": 2, "minecraft:sharpness": 5 }, "unbreakable": {} } } } ``` ## Best Practices 1. **Use meaningful names** - Recipe file names should describe the output 2. **Group related recipes** - Use the `group` field for recipe book organization 3. **Prefer tags** - Use item tags for flexible ingredient matching 4. **Set categories** - Help players find recipes in the recipe book 5. **Test in-game** - Verify recipes work as expected in all crafting interfaces 6. **Consider balance** - Ensure custom recipes maintain game balance ## See Also - [Advancements](./advancements) - Unlock recipes as advancement rewards - [Components](../concepts/components) - Customize recipe result items - [Commands](../commands/commands) - Give or take recipes with commands - [Tags](./tags) - Use item tags for flexible ingredient matching ### External Resources - [Minecraft Wiki: Recipe](https://minecraft.wiki/w/Recipe) - Official JSON format reference - [Minecraft Wiki: Crafting](https://minecraft.wiki/w/Crafting) - Crafting mechanics overview --- ## Tags --- root: .components.layouts.MarkdownLayout title: Tags nav-title: Tags description: Create and manage tags for grouping game elements with Kore's type-safe DSL keywords: minecraft, datapack, kore, tags, grouping, blocks, items, entities, functions date-created: 2026-02-03 date-modified: 2026-02-03 routeOverride: /docs/data-driven/tags --- # Tags Tags are JSON structures used in data packs to group related game elements together. They allow you to reference multiple items, blocks, entities, or other resources as a single unit. Tags are extensively used in commands, loot tables, advancements, recipes, and other data-driven features. ## Basic Usage Kore provides a generic `tag` function as well as specialized helper functions for each tag type: ```kotlin // Generic tag with explicit type tag("my_blocks", "block") { add(Blocks.STONE) add(Blocks.GRANITE) add(Blocks.DIORITE) } // Specialized helper function blockTag("my_blocks") { add(Blocks.STONE) add(Blocks.GRANITE) add(Blocks.DIORITE) } ``` This creates a tag file at `data//tags/block/my_blocks.json`. ## Adding Values There are several ways to add values to a tag: ### Simple Addition ```kotlin blockTag("building_blocks") { // Add a single block add(Blocks.STONE) // Using operators this += Blocks.COBBLESTONE this += "minecraft:granite" // Add with namespace add("custom_stone", namespace = "mymod") } ``` ### Adding Other Tags You can include other tags within a tag by prefixing with `#`: ```kotlin blockTag("all_stones") { // Reference another tag add("#minecraft:stone_bricks", tag = true) // Or using the name/namespace form add("base_stone_overworld", namespace = "minecraft", tag = true) } ``` ### Optional Entries Mark entries as optional with the `required` parameter. Optional entries won't cause errors if they don't exist: ```kotlin itemTag("optional_items") { add(Items.DIAMOND, required = true) // Must exist add("mymod:custom_gem", required = false) // Optional // Using TagEntry directly this += TagEntry("minecraft:emerald", required = false) } ``` ### Replace Mode By default, tags merge with existing tags of the same name. Set `replace = true` to completely override: ```kotlin // This will replace the vanilla tag entirely blockTag("logs", namespace = "minecraft", replace = true) { add(Blocks.OAK_LOG) add(Blocks.BIRCH_LOG) // Other logs won't be included } ``` ## Tag Types Kore provides specialized helper functions for all tag types. Here are the most commonly used ones: ### Block Tags ```kotlin blockTag("fragile_blocks") { add(Blocks.GLASS) add(Blocks.ICE) add(Blocks.GLOWSTONE) } ``` ### Item Tags ```kotlin itemTag("valuable_gems") { add(Items.DIAMOND) add(Items.EMERALD) add(Items.AMETHYST_SHARD) } ``` ### Entity Type Tags ```kotlin entityTypeTag("friendly_mobs") { add(EntityTypes.VILLAGER) add(EntityTypes.IRON_GOLEM) add(EntityTypes.CAT) } ``` ### Function Tags Function tags are special - they define groups of functions that can be called together or triggered by game events: ```kotlin // Create functions to be tagged function("on_load") { say("Datapack loaded!") } function("setup_scores") { scoreboard.objectives.add("kills", ScoreboardCriteria.PLAYER_KILL_COUNT) } // Tag them to run on load functionTag("load", namespace = "minecraft") { add("on_load", namespace = name) add("setup_scores", namespace = name) } ``` The `minecraft:load` and `minecraft:tick` function tags are special: - `minecraft:load` - Functions run once when the datapack loads - `minecraft:tick` - Functions run every game tick ### Biome Tags ```kotlin biomeTag("hot_biomes") { add(Biomes.DESERT) add(Biomes.BADLANDS) add(Biomes.SAVANNA) } ``` ### Damage Type Tags ```kotlin damageTypeTag("magic_damage") { add(DamageTypes.MAGIC) add(DamageTypes.INDIRECT_MAGIC) add(DamageTypes.DRAGON_BREATH) } ``` ### Enchantment Tags ```kotlin enchantmentTag("combat_enchants") { add(Enchantments.SHARPNESS) add(Enchantments.SMITE) add(Enchantments.BANE_OF_ARTHROPODS) } ``` ### Fluid Tags ```kotlin fluidTag("dangerous_fluids") { add(Fluids.LAVA) add(Fluids.FLOWING_LAVA) } ``` ## Complete List of Tag Helpers Kore provides helpers for all vanilla tag types: | Function | Tag Type | Path | |-------------------------------|----------------------|---------------------------------------------| | `bannerPatternTag` | Banner patterns | `tags/banner_pattern` | | `biomeTag` | Biomes | `tags/worldgen/biome` | | `blockTag` | Blocks | `tags/block` | | `catVariantTag` | Cat variants | `tags/cat_variant` | | `configuredCarverTag` | World carvers | `tags/worldgen/configured_carver` | | `configuredFeatureTag` | World features | `tags/worldgen/configured_feature` | | `configuredStructureTag` | Structures | `tags/worldgen/structure` | | `damageTypeTag` | Damage types | `tags/damage_type` | | `enchantmentTag` | Enchantments | `tags/enchantment` | | `entityTypeTag` | Entity types | `tags/entity_type` | | `flatLevelGeneratorPresetTag` | Flat world presets | `tags/worldgen/flat_level_generator_preset` | | `fluidTag` | Fluids | `tags/fluid` | | `frogVariantTag` | Frog variants | `tags/frog_variant` | | `functionTag` | Functions | `tags/function` | | `gameEventTag` | Game events | `tags/game_event` | | `instrumentTag` | Goat horns | `tags/instrument` | | `itemTag` | Items | `tags/item` | | `noiseSettingsTag` | Noise settings | `tags/worldgen/noise_settings` | | `noiseTag` | Noise | `tags/worldgen/noise` | | `paintingVariantTag` | Paintings | `tags/painting_variant` | | `pigVariantTag` | Pig variants | `tags/pig_variant` | | `placedFeatureTag` | Placed features | `tags/worldgen/placed_feature` | | `pointOfInterestTypeTag` | POI types | `tags/point_of_interest_type` | | `processorListTag` | Structure processors | `tags/worldgen/processor_list` | | `structureTag` | Structures | `tags/worldgen/structure` | | `templatePoolTag` | Jigsaw pools | `tags/worldgen/template_pool` | | `trimMaterialTag` | Trim materials | `tags/trim_material` | | `trimPatternTag` | Trim patterns | `tags/trim_pattern` | | `wolfVariantTag` | Wolf variants | `tags/wolf_variant` | | `worldPresetTag` | World presets | `tags/worldgen/world_preset` | ## Modifying Existing Tags Use `addToTag` to append to an existing tag without creating duplicates: ```kotlin // First creation blockTag("my_ores") { add(Blocks.IRON_ORE) add(Blocks.GOLD_ORE) } // Later in code, add more entries addToTag("my_ores", "block") { add(Blocks.DIAMOND_ORE) add(Blocks.EMERALD_ORE) } ``` ## Using Tags in Commands Tags can be referenced in commands with the `#` prefix: ```kotlin function("clear_valuables") { // Clear all items matching a tag clear(allPlayers(), tag = ItemTagArgument("valuable_gems", name)) } function("kill_hostiles") { // Kill entities matching a tag kill(allEntities { type = "#minecraft:raiders" }) } ``` ## Using Tags in Predicates Tags work seamlessly with [Predicates](./predicates): ```kotlin predicate("holding_tool") { matchTool { items(Tags.Item.PICKAXES) } } predicate("in_hot_biome") { locationCheck { biomes(BiomeTagArgument("hot_biomes", name)) } } ``` ## Using Tags in Recipes Tags are commonly used in [Recipes](./recipes) for flexible ingredient matching: ```kotlin craftingShapeless("any_planks_to_sticks") { ingredient(Tags.Item.PLANKS) ingredient(Tags.Item.PLANKS) result(Items.STICK, 4) } ``` ## Generated JSON A basic tag generates JSON like this: ```json { "replace": false, "values": [ "minecraft:stone", "minecraft:granite", "minecraft:diorite" ] } ``` With optional entries: ```json { "replace": false, "values": [ "minecraft:diamond", { "id": "mymod:custom_gem", "required": false } ] } ``` With tag references: ```json { "replace": false, "values": [ "#minecraft:stone_bricks", "minecraft:cobblestone" ] } ``` ## Best Practices 1. **Use meaningful names**: Name tags based on their purpose (e.g., `mineable/pickaxe` not `pickaxe_blocks`) 2. **Leverage existing tags**: Reference vanilla tags when appropriate instead of duplicating entries 3. **Keep tags focused**: Each tag should serve a single, clear purpose 4. **Use optional entries**: Mark modded content as `required = false` for cross-mod compatibility 5. **Avoid replace when possible**: Merging with existing tags maintains compatibility with other datapacks ## See Also - [Predicates](./predicates) - Use tags in predicate conditions - [Recipes](./recipes) - Use tags for flexible recipe ingredients - [Loot Tables](./loot-tables) - Use tags in loot conditions - [Functions](../commands/functions) - Creating functions to use with function tags - [Trims](./trims) - Trim material and pattern tags ### External Resources - [Minecraft Wiki: Tag (Java Edition)](https://minecraft.wiki/w/Tag_(Java_Edition)) - Complete reference for all tag types and vanilla tags --- ## Trims --- root: .components.layouts.MarkdownLayout title: Trims nav-title: Trims description: Create custom armor trim materials and patterns with Kore's type-safe DSL keywords: minecraft, datapack, kore, trims, armor, trim material, trim pattern, customization date-created: 2026-02-03 date-modified: 2026-02-03 routeOverride: /docs/data-driven/trims --- # Trims Armor trims are a customization system that allows players to add decorative patterns to their armor pieces. Trims consist of two components: **materials** (which determine the color/texture) and **patterns ** (which determine the shape/design). Kore provides type-safe DSL builders for creating custom trim materials and patterns. ## Trim Materials Trim materials define the color palette and appearance when a trim is applied to armor. Each material specifies: - **Asset name**: Points to the color palette texture - **Description**: The text shown in-game when hovering over trimmed armor - **Override armor materials**: Optional per-armor-type color overrides (e.g., different colors for netherite vs. iron armor) ### Basic Usage ```kotlin trimMaterial("ruby", TrimColorPalettes.AMETHYST, textComponent("Ruby Trim")) { description("Ruby", Color.RED) } ``` This creates a trim material file at `data//trim_material/ruby.json`. ### Material with Armor Overrides Some materials look different depending on the base armor material. For example, netherite armor uses a darker variant: ```kotlin trimMaterial("custom_gold", TrimColorPalettes.GOLD, textComponent("Custom Gold")) { description("Custom Gold Trim", Color.GOLD) overrideArmorMaterial(ArmorMaterial.NETHERITE, Color.hex("4a3c2e")) } ``` You can also set multiple overrides at once: ```kotlin trimMaterial("rainbow", TrimColorPalettes.AMETHYST, textComponent("Rainbow")) { description("Rainbow Trim") overrideArmorMaterials( ArmorMaterial.IRON to Color.hex("c0c0c0"), ArmorMaterial.GOLD to Color.hex("ffd700"), ArmorMaterial.DIAMOND to Color.hex("00ffff"), ArmorMaterial.NETHERITE to Color.hex("4a4a4a") ) } ``` ### Generated JSON A trim material generates JSON like this: ```json { "asset_name": "minecraft:amethyst", "description": { "text": "Ruby", "color": "#FF0000" } } ``` With armor overrides: ```json { "asset_name": "minecraft:gold", "description": { "text": "Custom Gold Trim", "color": "gold" }, "override_armor_materials": { "netherite": "#4a3c2e" } } ``` ## Trim Patterns Trim patterns define the visual design applied to armor. Each pattern specifies: - **Asset ID**: Points to the pattern texture model - **Description**: The text shown in-game when hovering over trimmed armor - **Decal**: Whether the pattern should render as a decal overlay (like netherite patterns) ### Basic Usage ```kotlin trimPattern("stripes", Models.TRIMS_MODELS_ARMOR_COAST, textComponent("Stripes")) { description("Striped Pattern", Color.GRAY) } ``` This creates a trim pattern file at `data//trim_pattern/stripes.json`. ### Pattern as Decal Setting `decal = true` makes the pattern render as an overlay, which is useful for patterns that should appear on top of the base armor texture without replacing it (similar to how netherite trim patterns work): ```kotlin trimPattern("overlay", Models.TRIMS_MODELS_ARMOR_SENTRY, textComponent("Overlay"), decal = true) { description("Overlay Pattern") } ``` ### Generated JSON A trim pattern generates JSON like this: ```json { "asset_id": "minecraft:trims/models/armor/coast", "description": { "text": "Striped Pattern", "color": "gray" }, "decal": false } ``` With decal enabled: ```json { "asset_id": "minecraft:trims/models/armor/sentry", "description": { "text": "Overlay Pattern" }, "decal": true } ``` ## See Also - [Chat Components](../concepts/chat_components) - For trim description text formatting - [Tags](./tags) - Organize trim materials and patterns into groups ### External Resources - [Minecraft Wiki: Tutorial - Adding custom trims](https://minecraft.wiki/w/Tutorial:Adding_custom_trims) - Official guide for creating custom trims - [Minecraft Wiki: Armor - Trimming](https://minecraft.wiki/w/Armor#Trimming) - Information about armor trimming mechanics --- ## Variants --- root: .components.layouts.MarkdownLayout title: Variants nav-title: Variants description: Define entity and painting variants with Kore's type-safe DSL keywords: minecraft, datapack, kore, variants, cat, cow, chicken, frog, pig, wolf, painting date-created: 2026-02-03 date-modified: 2026-02-03 routeOverride: /docs/data-driven/variants --- # Variants Variants allow you to customize the appearance and spawn conditions of various entities and paintings in Minecraft. Kore provides type-safe DSL builders for creating custom variants for cats, cows, chickens, frogs, pigs, wolves, and paintings. ## Entity Variants ### Spawn Conditions Most entity variants support spawn conditions that control when and where the variant appears. Available condition types: - **add(priority)**: Base condition with just a priority - **biome(priority, biomes...)**: Spawn in specific biomes or biome tags - **moonBrightness(priority, value)**: Spawn based on moon brightness (single value) - **moonBrightness(priority, min, max)**: Spawn based on moon brightness (range) - **structures(priority, structures...)**: Spawn near specific structures or structure tags Higher priority values take precedence when multiple conditions match. ### Cat Variants Cat variants define the texture and spawn conditions for cats. You can specify biomes, moon brightness, and structures as spawn conditions. ```kotlin catVariant("test_cat_variant", Textures.Entity.Cat.TABBY) { spawnConditions { add(10) biome(5, Biomes.PLAINS) biome(2, Tags.Worldgen.Biome.IS_OVERWORLD) moonBrightness(1, 1.0) moonBrightness(1, 0.5, 0.75) structures(0, ConfiguredStructures.VILLAGE_PLAINS) } } ``` Produces JSON: ```json { "asset_id": "minecraft:entity/cat/tabby", "spawn_conditions": [ { "priority": 10 }, { "priority": 5, "condition": { "type": "minecraft:biome", "biomes": "minecraft:plains" } }, { "priority": 2, "condition": { "type": "minecraft:biome", "biomes": "#minecraft:is_overworld" } }, { "priority": 1, "condition": { "type": "minecraft:moon_brightness", "range": 1.0 } }, { "priority": 1, "condition": { "type": "minecraft:moon_brightness", "range": { "min": 0.5, "max": 0.75 } } }, { "priority": 0, "condition": { "type": "minecraft:structure", "structures": "minecraft:village_plains" } } ] } ``` ### Cow Variants Cow variants define the texture, model, and spawn conditions for cows. ```kotlin cowVariant("test_cow_variant", Textures.Entity.Cow.COLD_COW, CowModel.COLD) { spawnConditions { structures(0, Tags.Worldgen.Structure.MINESHAFT) } } ``` Produces JSON: ```json { "asset_id": "minecraft:entity/cow/cold_cow", "model": "cold", "spawn_conditions": [ { "priority": 0, "condition": { "type": "minecraft:structure", "structures": "#minecraft:mineshaft" } } ] } ``` ### Chicken Variants Chicken variants define the texture, model, and spawn conditions for chickens. ```kotlin chickenVariant("test_chicken_variant", Textures.Entity.Chicken.TEMPERATE_CHICKEN, ChickenModel.NORMAL) { spawnConditions { structures(0, Tags.Worldgen.Structure.VILLAGE) } } ``` Produces JSON: ```json { "asset_id": "minecraft:entity/chicken/temperate_chicken", "model": "normal", "spawn_conditions": [ { "priority": 0, "condition": { "type": "minecraft:structure", "structures": "#minecraft:village" } } ] } ``` ### Frog Variants Frog variants define the texture and spawn conditions for frogs. ```kotlin frogVariant("test_frog_variant", Textures.Entity.Frog.TEMPERATE_FROG) { spawnConditions { add(10) biome(5, Biomes.SNOWY_PLAINS) biome(2, Tags.Worldgen.Biome.SPAWNS_COLD_VARIANT_FROGS) moonBrightness(1, 1.0) moonBrightness(1, 0.5, 0.75) structures(0, ConfiguredStructures.END_CITY) } } ``` Produces JSON: ```json { "asset_id": "minecraft:entity/frog/temperate_frog", "spawn_conditions": [ { "priority": 10 }, { "priority": 5, "condition": { "type": "minecraft:biome", "biomes": "minecraft:snowy_plains" } }, { "priority": 2, "condition": { "type": "minecraft:biome", "biomes": "#minecraft:spawns_cold_variant_frogs" } }, { "priority": 1, "condition": { "type": "minecraft:moon_brightness", "range": 1.0 } }, { "priority": 1, "condition": { "type": "minecraft:moon_brightness", "range": { "min": 0.5, "max": 0.75 } } }, { "priority": 0, "condition": { "type": "minecraft:structure", "structures": "minecraft:end_city" } } ] } ``` ### Pig Variants Pig variants define the texture, model, and spawn conditions for pigs. ```kotlin pigVariant("test_pig_variant", Textures.Entity.Pig.COLD_PIG, PigModel.COLD) { spawnConditions { structures(0, Tags.Worldgen.Structure.ON_TREASURE_MAPS) } } ``` Produces JSON: ```json { "asset_id": "minecraft:entity/pig/cold_pig", "model": "cold", "spawn_conditions": [ { "priority": 0, "condition": { "type": "minecraft:structure", "structures": "#minecraft:on_treasure_maps" } } ] } ``` ### Wolf Variants Wolf variants define separate textures for angry, tame, and wild states, along with spawn conditions. ```kotlin wolfVariant("test_wolf_variant") { assets( angry = Textures.Entity.Wolf.WOLF_STRIPED, tame = Textures.Entity.Wolf.WOLF_RUSTY_ANGRY, wild = Textures.Entity.Wolf.WOLF_BLACK, ) spawnConditions { biome(5, Biomes.OCEAN, Biomes.SNOWY_SLOPES) } } ``` Produces JSON: ```json { "assets": { "angry": "minecraft:entity/wolf/wolf_striped", "tame": "minecraft:entity/wolf/wolf_rusty_angry", "wild": "minecraft:entity/wolf/wolf_black" }, "spawn_conditions": [ { "priority": 5, "condition": { "type": "minecraft:biome", "biomes": [ "minecraft:ocean", "minecraft:snowy_slopes" ] } } ] } ``` ### Wolf Sound Variants Wolf sound variants define custom sounds for wolves. Sound variants are independent of color variants and spawning biome. Wolves will make the sounds associated with their variant when they bark, pant, whine, growl, die, or get hurt. ```kotlin wolfSoundVariant("funny") { ambientSound = SoundEvents.Entity.Pig.AMBIENT deathSound = SoundEvents.Entity.Creeper.DEATH growlSound = SoundEvents.Entity.Player.LEVELUP hurtSound = SoundEvents.Entity.Zombie.HURT pantSound = SoundEvents.Entity.EnderDragon.FLAP whineSound = SoundEvents.Entity.Cat.PURR } ``` Produces JSON: ```json { "ambient_sound": "minecraft:entity.pig.ambient", "death_sound": "minecraft:entity.creeper.death", "growl_sound": "minecraft:entity.player.levelup", "hurt_sound": "minecraft:entity.zombie.hurt", "pant_sound": "minecraft:entity.ender_dragon.flap", "whine_sound": "minecraft:entity.cat.purr" } ``` ## Other Variants ### Painting Variants Painting variants define custom paintings with dimensions and optional metadata like author and title. ```kotlin // Basic painting variant paintingVariant( assetId = Textures.Painting.KEBAB, height = 16, width = 16 ) ``` Produces JSON: ```json { "asset_id": "minecraft:kebab", "height": 16, "width": 16 } ``` With default dimensions (1x1): ```kotlin paintingVariant( assetId = Textures.Painting.AZTEC ) ``` Produces JSON: ```json { "asset_id": "minecraft:aztec", "height": 1, "width": 1 } ``` With author and title: ```kotlin paintingVariant( assetId = Textures.Painting.AZTEC, ) { author = textComponent("Ayfri") title = textComponent("Aztec") } ``` Produces JSON: ```json { "asset_id": "minecraft:aztec", "height": 1, "width": 1, "author": "Ayfri", "title": "Aztec" } ``` ### See Also - [Chat Components](../concepts/chat_components) - For painting title and author text formatting - [Tags](./tags) - Use variant tags for spawn conditions --- ## World Generation --- root: .components.layouts.MarkdownLayout title: World Generation nav-title: Worldgen description: Overview of custom world generation (1.21+) with Kore's Kotlin DSL. keywords: minecraft, datapack, kore, worldgen, dimension, biome, features, structures, noise date-created: 2025-08-11 date-modified: 2026-02-03 routeOverride: /docs/data-driven/worldgen --- # World Generation This guide covers custom world generation using Kore's Kotlin DSL. It maps common datapack JSON files to concise Kotlin builders. ## What is World Generation? World generation (worldgen) is the procedural generation process Minecraft uses to algorithmically generate terrain, biomes, features, and structures. Because there are over 18 quintillion (2⁶⁴) possible worlds, the game generates them using randomness, algorithms, and some manually built decorations. The generation process uses **gradient noise algorithms** (like Perlin noise) to ensure terrain has both continuity and randomness. Multiple noise functions with different frequencies and amplitudes (called **octaves**) are combined to create natural-looking variation with hills, valleys, and other terrain features. See [World generation](https://minecraft.wiki/w/World_generation) for the full technical breakdown. ## Generation Steps Minecraft generates chunks through multiple sequential steps. Incomplete chunks are called **proto-chunks**, while fully generated chunks accessible to players are **level chunks**: 1. **structures_starts** - Calculate starting points for structure pieces 2. **structures_references** - Store references to nearby structure starts 3. **biomes** - Determine and store biomes (no terrain yet) 4. **noise** - Generate base terrain shape and liquid bodies 5. **surface** - Replace terrain surface with biome-dependent blocks 6. **carvers** - Carve caves and canyons 7. **features** - Place features, structures, and generate heightmaps 8. **light** - Calculate light levels for all blocks 9. **spawn** - Spawn initial mobs 10. **full** - Generation complete, proto-chunk becomes level chunk Reference: [World generation steps](https://minecraft.wiki/w/World_generation#Steps) ## Documentation Structure World generation is split into focused pages: - [**Biomes**](./worldgen/biomes) - Climate, visuals, mob spawns, carvers, and feature lists - [**Features**](./worldgen/features) - Configured and placed features (trees, ores, vegetation) - [**Noise & Terrain**](./worldgen/noise) - Density functions, noise definitions, and noise settings - [**Dimensions**](./worldgen/dimensions) - Dimensions and dimension types - [**Structures**](./worldgen/structures) - Structures, template pools, processors, and structure sets - [**World Presets**](./worldgen/world-presets) - World presets and flat level generator presets ## Decoration Steps Minecraft runs 11 decoration steps in order for each chunk; structures of a step place before features in that step. | Step | Name | Examples | |------|--------------------------|---------------------------------------------| | 1 | `raw_generation` | Small end islands | | 2 | `lakes` | Lava lakes | | 3 | `local_modifications` | Geodes, icebergs | | 4 | `underground_structures` | Trial chambers, mineshafts | | 5 | `surface_structures` | Desert wells, blue ice patches | | 6 | `strongholds` | Unused (strongholds use surface_structures) | | 7 | `underground_ores` | Ore blobs, sand/gravel/clay disks | | 8 | `underground_decoration` | Infested blobs, nether gravel/blackstone | | 9 | `fluid_springs` | Water/lava springs | | 10 | `vegetal_decoration` | Trees, cacti, kelp, vegetation | | 11 | `top_layer_modification` | Freeze top layer | Reference: [Decoration steps](https://minecraft.wiki/w/World_Generation#Decoration_steps) ## Output Paths Kore APIs generate JSON under standard datapack directories (replace `` with your namespace): | API | Output Path | |---------------------------------|--------------------------------------------------------------| | `biome(...)` | `data//worldgen/biome/.json` | | `configuredCarver(...)` | `data//worldgen/configured_carver/.json` | | `configuredFeature(...)` | `data//worldgen/configured_feature/.json` | | `densityFunction(...)` | `data//worldgen/density_function/.json` | | `dimension(...)` | `data//dimension/.json` | | `dimensionType(...)` | `data//dimension_type/.json` | | `flatLevelGeneratorPreset(...)` | `data//worldgen/flat_level_generator_preset/.json` | | `noise(...)` | `data//worldgen/noise/.json` | | `noiseSettings(...)` | `data//worldgen/noise_settings/.json` | | `processorList(...)` | `data//worldgen/processor_list/.json` | | `structureSet(...)` | `data//worldgen/structure_set/.json` | | `structures { ... }` | `data//worldgen/structure/.json` | | `templatePool(...)` | `data//worldgen/template_pool/.json` | | `worldPreset(...)` | `data//worldgen/world_preset/.json` | ## Quick Start Example ```kotlin val dp = DataPack("my_pack") // 1) Dimension type val dimType = dp.dimensionType("example_type") { minY = -64 height = 384 hasSkylight = true } // 2) Noise settings val terrain = dp.noiseSettings("example_noise") { noiseOptions(-64, 384, 1, 2) } // 3) Biome with features val plains = dp.biome("example_plains") { temperature = 0.8f downfall = 0.4f hasPrecipitation = true effects { skyColor = 0x78A7FF fogColor = 0xC0D8FF waterColor = 0x3F76E4 waterFogColor = 0x050533 } } // 4) Dimension val dim = dp.dimension("example_dimension", type = dimType) { // noiseGenerator(settings = terrain, biomeSource = ...) } // 5) World preset dp.worldPreset("example_preset") { dimension(DimensionTypes.OVERWORLD) { type = dimType } } ``` ## Tips & Testing - **In-game commands:** - Teleport: `/execute in : run tp @s 0 200 0` - Locate: `/locate structure :` - Reload: `/reload` - **Validation:** Check your configs against the [Minecraft Wiki](https://minecraft.wiki/w/World_generation) JSON schemas. - **Performance:** Keep feature counts and structure spacing reasonable. - **Testing:** Use GameTest for deterministic validation; see [Test Features](../advanced/test-features). ## Cross-References - [Predicates](../data-driven/predicates) - Condition logic for features - [Test Features](../advanced/test-features) - Automated validation with GameTest --- ## Biomes --- root: .components.layouts.MarkdownLayout title: Biomes nav-title: Biomes description: Define biomes with climate, effects, spawns, carvers, and features using Kore's DSL. keywords: minecraft, datapack, kore, worldgen, biome, carver, spawner, effects date-created: 2026-02-03 date-modified: 2026-02-03 routeOverride: /docs/data-driven/worldgen/biomes --- # Biomes Biomes define climate, visuals, mob spawns, carvers, and the placed features list for each decoration step. In Minecraft, biomes control not just the terrain appearance but also weather behavior, mob spawning rules, and which features generate. ## How Biomes Work In the Overworld, biome placement is determined by 6 climate parameters: - **Temperature** - Controls snow/ice coverage and vegetation types (5 levels from frozen to hot) - **Humidity** - Affects vegetation density (5 levels from arid to humid) - **Continentalness** - Determines ocean/beach/inland placement - **Erosion** - Controls flat vs mountainous terrain (7 levels) - **Weirdness** - Triggers biome variants (e.g., Jungle → Bamboo Jungle) - **Depth** - Determines surface vs cave biomes These parameters form a 6D space where each biome occupies defined intervals. The game selects the closest matching biome for any given location. References: [Biome](https://minecraft.wiki/w/Biome), [Biome definition](https://minecraft.wiki/w/Biome_definition) ## Basic Biome ```kotlin val myBiome = dp.biome("my_biome") { temperature = 0.8f downfall = 0.4f hasPrecipitation = true effects { skyColor = 0x78A7FF fogColor = 0xC0D8FF waterColor = 0x3F76E4 waterFogColor = 0x050533 } } ``` ## Effects The `effects` block controls visual and audio aspects of the biome. These settings define the atmosphere players experience, from sky color to ambient sounds. Reference: [Biome definition - Effects](https://minecraft.wiki/w/Biome_definition#Effects) ```kotlin effects { // Required colors skyColor = 0x78A7FF fogColor = 0xC0D8FF waterColor = 0x3F76E4 waterFogColor = 0x050533 // Optional colors foliageColor = 0x59AE30 grassColor = 0x79C05A // Optional ambient effects // ambientSound = ... // moodSound { ... } // additionsSound { ... } // music { ... } // particle { ... } } ``` ## Spawners Define mob spawn rules per category. Each spawner entry specifies the entity type, spawn weight (relative probability), and count range. Higher weights mean more frequent spawns relative to other entries in the same category. Reference: [Biome definition - Mob spawning](https://minecraft.wiki/w/Biome_definition#Mob_spawning) ```kotlin spawners { creature { spawner(EntityTypes.COW, weight = 6, minCount = 2, maxCount = 4) spawner(EntityTypes.SHEEP, weight = 8, minCount = 2, maxCount = 4) } monster { spawner(EntityTypes.SKELETON, weight = 80, minCount = 1, maxCount = 2) spawner(EntityTypes.ZOMBIE, weight = 80, minCount = 1, maxCount = 2) } // Other categories: ambient, waterCreature, undergroundWaterCreature, waterAmbient, misc, axolotls } ``` ## Spawn Costs Spawn costs control mob density using an energy budget system. Each mob type has an `energyBudget` (max population density) and `charge` ( cost per mob). This prevents overcrowding while allowing natural mob distribution. Reference: [Biome definition - Spawn costs](https://minecraft.wiki/w/Biome_definition#Spawn_costs) ```kotlin spawnCosts { this[EntityTypes.COW] = spawnCost(energyBudget = 1.2f, charge = 0.1f) this[EntityTypes.SHEEP] = spawnCost(energyBudget = 1.0f, charge = 0.08f) } ``` ## Carvers Carvers hollow out terrain to create caves and canyons. They run during the `carvers` generation step, after terrain noise but before features. Two carving modes exist: `air` for standard caves and `liquid` for underwater caves. Reference: [Carver](https://minecraft.wiki/w/Carver) ```kotlin carvers { air(myCaveCarver) // Carves air (caves) liquid(myUnderwaterCave) // Carves underwater caves } ``` See [Carvers](#carvers-cavescanyons) below for creating configured carvers. ## Features Features are attached to biomes via decoration steps. Each step runs in order during chunk generation, with structures placing before features within the same step. See the [main worldgen page](../worldgen#decoration-steps) for the full step list. Reference: [Biome definition - Features](https://minecraft.wiki/w/Biome_definition#Features) ```kotlin features { fluidSprings = listOf(...) lakes = listOf(...) localModifications = listOf(...) rawGeneration = listOf(...) strongholds = listOf(...) surfaceStructures = listOf(...) topLayerModification = listOf(...) undergroundDecoration = listOf(...) undergroundOres = listOf(orePlaced) undergroundStructures = listOf(...) vegetalDecoration = listOf(treePlaced, flowerPlaced) } ``` See [Features](./features) for creating configured and placed features. --- # Carvers (Caves/Canyons) Configured carvers remove terrain to form cave systems and canyons. They use noise-based algorithms to create natural-looking underground spaces. Carvers run after terrain generation but before features, ensuring caves don't destroy placed decorations. Minecraft has two carver types: - **Cave carvers** - Create winding tunnel systems with variable radius - **Canyon carvers** - Create deep ravines with steep walls References: [Carver](https://minecraft.wiki/w/Carver), [Configured carver](https://minecraft.wiki/w/Configured_carver) ## Cave Carver ```kotlin val caveCfg = caveConfig { floorLevel = constant(-0.2f) horizontalRadiusMultiplier = constant(1.0f) lavaLevel = absolute(8) probability = 0.08 verticalRadiusMultiplier = constant(0.7f) y = uniformHeightProvider(32, 128) yScale = constant(0.5f) } val cave = dp.configuredCarver("my_cave", caveCfg) {} ``` ## Canyon Carver ```kotlin val canyonCfg = canyonConfig { lavaLevel = absolute(8) probability = 0.02 y = uniformHeightProvider(10, 67) yScale = constant(3.0f) // Additional canyon-specific settings... } val canyon = dp.configuredCarver("my_canyon", canyonCfg) {} ``` --- # Complete Biome Example ```kotlin fun DataPack.createHighlandsBiome() { // Create a cave carver val caveCfg = caveConfig { floorLevel = constant(-0.2f) horizontalRadiusMultiplier = constant(1.0f) lavaLevel = absolute(8) probability = 0.08 verticalRadiusMultiplier = constant(0.7f) y = uniformHeightProvider(32, 128) yScale = constant(0.5f) } val cave = configuredCarver("highlands_cave", caveCfg) {} // Create placed features (see Features page) val treePlaced = /* ... */ val orePlaced = /* ... */ // Create the biome biome("highlands") { temperature = 0.8f downfall = 0.3f hasPrecipitation = true effects { fogColor = 0xBFEFFF skyColor = 0x99D9FF waterColor = 0x34A7F0 waterFogColor = 0x0A2C4F } spawners { creature { spawner(EntityTypes.COW, 6, 2, 4) spawner(EntityTypes.SHEEP, 8, 2, 4) } monster { spawner(EntityTypes.SKELETON, 80, 1, 2) spawner(EntityTypes.ZOMBIE, 80, 1, 2) } } spawnCosts { this[EntityTypes.COW] = spawnCost(1.2f, 0.1f) this[EntityTypes.SHEEP] = spawnCost(1.0f, 0.08f) } carvers { air(cave) } features { undergroundOres = listOf(orePlaced) vegetalDecoration = listOf(treePlaced) } } } ``` --- ## Dimensions --- root: .components.layouts.MarkdownLayout title: Dimensions nav-title: Dimensions description: Create custom dimensions and dimension types with Kore's DSL. keywords: minecraft, datapack, kore, worldgen, dimension, dimension type, generator date-created: 2026-02-03 date-modified: 2026-02-03 routeOverride: /docs/data-driven/worldgen/dimensions --- # Dimensions Dimensions are complete, separate worlds within Minecraft. Each dimension combines a **dimension type** (world rules like height, lighting, and behavior) with a **generator** (how terrain is created). Vanilla Minecraft has three dimensions: Overworld, Nether, and End. With datapacks, you can create unlimited custom dimensions with unique terrain, rules, and atmosphere. Players can travel between dimensions using portals or commands. References: [Dimension](https://minecraft.wiki/w/Dimension), [Dimension definition](https://minecraft.wiki/w/Dimension_definition), [Custom dimension](https://minecraft.wiki/w/Custom_dimension) --- ## Dimension Type Dimension types define the fundamental rules of a world: vertical bounds, lighting behavior, time flow, and special mechanics. These settings affect gameplay significantly-for example, `ultrawarm` dimensions evaporate water and make lava flow faster (like the Nether). Reference: [Dimension type](https://minecraft.wiki/w/Dimension_type) ```kotlin val myDimType = dp.dimensionType("my_dim_type") { ambientLight = 0f bedWorks = true hasCeiling = false hasRaids = true hasSkylight = true height = 384 logicalHeight = 384 minY = -64 natural = true piglinSafe = false respawnAnchorWorks = false ultrawarm = false } ``` ### Dimension Type Properties | Property | Description | |----------------------|-----------------------------------------| | `ambientLight` | Base light level (0.0 to 1.0) | | `bedWorks` | Beds can set spawn point | | `effects` | Visual effects (overworld/nether/end) | | `hasCeiling` | Whether dimension has bedrock ceiling | | `hasRaids` | Raids can occur | | `hasSkylight` | Whether sky provides light | | `height` | Total height (multiple of 16, max 4064) | | `infiniburn` | Block tag for infinite burning | | `logicalHeight` | Max height for teleportation/portals | | `minY` | Minimum Y coordinate (multiple of 16) | | `natural` | Compasses/clocks work normally | | `piglinSafe` | Piglins don't zombify | | `respawnAnchorWorks` | Respawn anchors can be used | | `ultrawarm` | Water evaporates, lava flows faster | --- ## Dimension A dimension combines a dimension type with a generator that produces terrain. The generator determines the terrain algorithm and biome distribution. ```kotlin val dim = dp.dimension("my_dimension", type = myDimType) { // Choose a generator (see below) } ``` ### Noise Generator The noise generator is the standard terrain generator used by vanilla dimensions. It combines **noise settings** (terrain shape algorithm) with a **biome source** (which biomes appear where). Reference: [Noise generator](https://minecraft.wiki/w/Dimension_definition#Noise_generator) ```kotlin dimension("my_dimension", type = myDimType) { noiseGenerator( settings = myNoiseSettings, biomeSource = /* BiomeSource */ ) } ``` #### Biome Sources Biome sources determine how biomes are distributed across the dimension. Different sources suit different use cases: Reference: [Biome source](https://minecraft.wiki/w/Biome_source) ```kotlin // Single biome everywhere (simplest option) noiseGenerator( settings = terrain, biomeSource = fixed(myBiome) ) // Checkerboard pattern noiseGenerator( settings = terrain, biomeSource = checkerboard(scale = 3, biome1, biome2, biome3) ) // Multi-noise (vanilla-like biome distribution) noiseGenerator( settings = terrain, biomeSource = multiNoise { // biome entries with climate parameters } ) // The End biome source noiseGenerator( settings = terrain, biomeSource = theEnd() ) ``` ### Flat Generator The flat generator creates superflat worlds with user-defined block layers. Useful for testing, creative building, or specialized gameplay. Reference: [Superflat](https://minecraft.wiki/w/Superflat) ```kotlin dimension("flat_world", type = myDimType) { flatGenerator(biome = Biomes.PLAINS) { layers { layer(Blocks.BEDROCK, height = 1) layer(Blocks.DIRT, height = 2) layer(Blocks.GRASS_BLOCK, height = 1) } // structureOverrides = ... } } ``` ### Debug Generator The debug generator creates a world showing every block state in a grid pattern. Primarily used for development and testing. Reference: [Debug mode](https://minecraft.wiki/w/Debug_mode) ```kotlin dimension("debug_world", type = myDimType) { debugGenerator() } ``` --- ## Complete Example ```kotlin fun DataPack.createSkyDimension() { // 1) Dimension type with high ambient light val skyType = dimensionType("sky_type") { ambientLight = 0.5f bedWorks = true hasCeiling = false hasRaids = false hasSkylight = true height = 256 logicalHeight = 256 minY = 0 natural = true piglinSafe = false respawnAnchorWorks = false ultrawarm = false } // 2) Simple noise settings val skyTerrain = noiseSettings("sky_terrain") { noiseOptions(minY = 0, height = 256, sizeHorizontal = 1, sizeVertical = 2) defaultBlock(Blocks.STONE) {} defaultFluid(Blocks.WATER) { this["level"] = "0" } } // 3) Create a biome val skyBiome = biome("sky_biome") { temperature = 0.5f downfall = 0.0f hasPrecipitation = false effects { skyColor = 0xFFFFFF fogColor = 0xFFFFFF waterColor = 0x3F76E4 waterFogColor = 0x050533 } } // 4) Create the dimension dimension("sky", type = skyType) { noiseGenerator( settings = skyTerrain, biomeSource = fixed(skyBiome) ) } } ``` --- ## Features --- root: .components.layouts.MarkdownLayout title: Features nav-title: Features description: Create configured and placed features (trees, ores, vegetation) with Kore's DSL. keywords: minecraft, datapack, kore, worldgen, configured feature, placed feature, tree, ore date-created: 2026-02-03 date-modified: 2026-02-03 routeOverride: /docs/data-driven/worldgen/features --- # Features Features are world generation elements like trees, ores, flowers, and other decorations placed during the `features` generation step. They represent everything from single blocks to complex multi-block structures like trees and geodes. ## Two-Part System Minecraft separates feature definition into two parts: - **Configured feature** - Defines *what* to place (tree species, ore type, flower) with all its parameters (block types, sizes, shapes) - **Placed feature** - Defines *where* and *how often* to place (count per chunk, height range, rarity, biome restrictions) This separation allows reusing the same configured feature with different placement rules. For example, one tree configuration can be placed densely in forests but sparsely in plains. References: [Configured feature](https://minecraft.wiki/w/Configured_feature), [Placed feature](https://minecraft.wiki/w/Placed_feature), [Feature](https://minecraft.wiki/w/Feature) --- ## Configured Features Configured features define the feature type and its parameters. Kore provides builder functions for common feature types. ### Tree Trees are complex features with trunk placers, foliage placers, and decorators. The trunk and foliage providers define which blocks to use, while placers control the shape. ```kotlin val treeCfg = tree { blobFoliagePlacer(radius = constant(2), offset = constant(0), height = 3) dirtProvider = simpleStateProvider(Blocks.DIRT) foliageProvider = simpleStateProvider(Blocks.OAK_LEAVES) straightTrunkPlacer(baseHeight = 6, heightRandA = 3, heightRandB = 1) trunkProvider = simpleStateProvider(Blocks.OAK_LOG) } val tree = dp.configuredFeature("my_tree", treeCfg) {} ``` ### Ore Ore features place clusters of blocks that replace existing terrain. The `size` controls maximum vein size, while `discardChanceOnAirExposure` prevents ores from generating in caves (set to 0 for full veins, 1 to skip all exposed blocks). Reference: [Ore feature](https://minecraft.wiki/w/Ore_(feature)) ```kotlin val oreCfg = ore( size = 10, // Max blocks per vein discardChanceOnAirExposure = 0.1, // Skip blocks exposed to air targets = listOf(Target()) // Rule tests for replacement ) val ore = dp.configuredFeature("my_ore", oreCfg) {} ``` ### Simple Block ```kotlin val flowerCfg = simpleBlock(toPlace = simpleStateProvider(Blocks.DANDELION)) val flower = dp.configuredFeature("my_flower", flowerCfg) {} ``` ### Other Feature Types Kore supports many feature types. Here are the most commonly used: | Feature Type | Description | Example Use | |------------------|-------------------------------|--------------------------------| | `blockPile` | Piles of blocks | Pumpkin patches, melon patches | | `diskFeature` | Circular disk of blocks | Clay, sand, gravel patches | | `fossilFeature` | Structure-based fossils | Underground fossils | | `geode` | Hollow structures with layers | Amethyst geodes | | `icebergFeature` | Iceberg structures | Ocean icebergs | | `lakeFeature` | Liquid pools | Underground lava lakes | | `randomPatch` | Scattered block placements | Flowers, grass, mushrooms | | `springFeature` | Fluid source blocks | Water/lava springs | Reference: [Feature types](https://minecraft.wiki/w/Configured_feature#Types) --- ## Placed Features Placed features wrap a configured feature with **placement modifiers** that control where and how often the feature generates. Modifiers are applied in sequence, filtering and transforming placement positions. Reference: [Placed feature](https://minecraft.wiki/w/Placed_feature) ```kotlin val treePlaced = dp.placedFeature("my_tree_placed", treeConfigured) { inSquare() count(constant(10)) heightRange(uniformHeightProvider(64, 128)) biome() } ``` ### Placement Modifiers Modifiers process in order, each one filtering or transforming the placement stream. Common patterns: - Start with `count()` or `rarityFilter()` to control frequency - Use `inSquare()` to spread horizontally within the chunk - Apply `heightRange()` or `heightmap()` for vertical positioning - End with `biome()` to respect biome boundaries Reference: [Placement modifier](https://minecraft.wiki/w/Placed_feature#Placement_modifiers) | Modifier | Description | |---------------------------------------|-------------------------------| | `biome()` | Only place in valid biomes | | `blockPredicateFilter(predicate)` | Custom block condition | | `count(n)` | Place n times per chunk | | `countOnEveryLayer(n)` | Place n times on every layer | | `environmentScan(...)` | Scan for valid placement | | `heightmap(type)` | Place relative to heightmap | | `heightRange(provider)` | Vertical placement range | | `inSquare()` | Spread horizontally in chunk | | `rarityFilter(chance)` | 1/chance probability to place | | `surfaceRelativeThresholdFilter(...)` | Surface-relative placement | | `surfaceWaterDepthFilter(maxDepth)` | Max water depth filter | ### Height Providers Height providers control vertical distribution. Different providers create different ore/feature distributions: - **Uniform** - Equal chance at all heights (good for evenly distributed ores) - **Trapezoid** - Peaks in the middle, tapers at edges (vanilla iron ore pattern) - **Very biased to bottom** - Concentrates near minimum Y (vanilla diamond pattern) Reference: [Height provider](https://minecraft.wiki/w/Height_provider) ```kotlin // Uniform distribution between min and max heightRange(uniformHeightProvider(minY = 0, maxY = 64)) // Triangular distribution (peaks at center) heightRange(trapezoidHeightProvider(minY = 0, maxY = 64, plateau = 20)) // Constant height heightRange(constantHeightProvider(y = 32)) // Relative to world bounds heightRange(veryBiasedToBottomHeightProvider(minY = 0, maxY = 64)) ``` --- ## Complete Example ```kotlin fun DataPack.createForestFeatures() { // 1) Tree configured feature val oakTreeCfg = tree { blobFoliagePlacer(radius = constant(2), offset = constant(0), height = 3) dirtProvider = simpleStateProvider(Blocks.DIRT) foliageProvider = simpleStateProvider(Blocks.OAK_LEAVES) straightTrunkPlacer(baseHeight = 5, heightRandA = 2, heightRandB = 0) trunkProvider = simpleStateProvider(Blocks.OAK_LOG) } val oakTree = configuredFeature("oak_tree", oakTreeCfg) {} // 2) Tree placed feature val oakTreePlaced = placedFeature("oak_tree_placed", oakTree) { inSquare() count(constant(8)) heightRange(uniformHeightProvider(64, 100)) biome() } // 3) Flower configured feature val flowerCfg = simpleBlock(toPlace = simpleStateProvider(Blocks.POPPY)) val flower = configuredFeature("forest_flower", flowerCfg) {} // 4) Flower placed feature val flowerPlaced = placedFeature("forest_flower_placed", flower) { inSquare() rarityFilter(4) heightRange(uniformHeightProvider(64, 100)) biome() } // 5) Ore configured feature val ironOreCfg = ore( size = 9, discardChanceOnAirExposure = 0.0, targets = listOf(Target()) ) val ironOre = configuredFeature("iron_ore", ironOreCfg) {} // 6) Ore placed feature val ironOrePlaced = placedFeature("iron_ore_placed", ironOre) { inSquare() count(constant(20)) heightRange(uniformHeightProvider(-64, 72)) biome() } // 7) Use in biome biome("custom_forest") { temperature = 0.7f downfall = 0.8f hasPrecipitation = true effects { skyColor = 0x78A7FF fogColor = 0xC0D8FF waterColor = 0x3F76E4 waterFogColor = 0x050533 } features { undergroundOres = listOf(ironOrePlaced) vegetalDecoration = listOf(oakTreePlaced, flowerPlaced) } } } ``` --- ## Noise & Terrain --- root: .components.layouts.MarkdownLayout title: Noise & Terrain nav-title: Noise description: Define terrain shaping with density functions, noise definitions, and noise settings. keywords: minecraft, datapack, kore, worldgen, noise, density function, noise settings, terrain date-created: 2026-02-03 date-modified: 2026-02-03 routeOverride: /docs/data-driven/worldgen/noise --- # Noise & Terrain Noise and density functions are the mathematical foundation of Minecraft's terrain generation. They control everything from mountain heights to cave shapes, creating the continuous, natural-looking landscapes players explore. ## How Terrain Generation Works Minecraft uses **density functions** to determine whether each position in 3D space should be solid or air. Positive density = solid block, negative density = air. These functions sample from **noise definitions** (Perlin noise with configurable octaves) to create smooth, natural variation. The **noise router** connects density functions to specific terrain aspects: base terrain shape, cave carving, aquifer placement, ore vein distribution, and biome parameters. References: [Density function](https://minecraft.wiki/w/Density_function), [Noise](https://minecraft.wiki/w/Noise), [Noise settings](https://minecraft.wiki/w/Noise_settings) --- ## Density Functions Density functions are composable mathematical operations that output a density value for any 3D position. They can be combined, transformed, and cached to build complex terrain shapes from simple primitives. Reference: [Density function](https://minecraft.wiki/w/Density_function) ```kotlin val df = dp.densityFunction("my_density", type = /* DensityFunctionType */) {} ``` ### Common Density Function Types | Type | Description | |-----------------------------------------------|--------------------------------| | `constant` | Fixed value everywhere | | `noise` | Sample from a noise definition | | `yClampedGradient` | Gradient based on Y coordinate | | `add`, `mul` | Combine two density functions | | `min`, `max` | Take min/max of two functions | | `blend_density` | Blend between functions | | `cache_2d`, `cache_once`, `cache_all_in_cell` | Caching wrappers | | `interpolated` | Smooth interpolation | | `flat_cache` | 2D cache for flat operations | | `spline` | Cubic spline interpolation | --- ## Noise Definitions Noise definitions configure Perlin noise parameters. Perlin noise creates smooth, continuous random values that look natural. **Octaves** layer multiple noise samples at different scales-lower octaves create large features (continents), higher octaves add fine detail (small hills). Reference: [Noise](https://minecraft.wiki/w/Noise) ```kotlin val noise = dp.noise("my_noise") { firstOctave = -7 amplitudes = listOf(1.0, 1.0, 0.5) } ``` ### Parameters | Parameter | Description | |---------------|-------------------------------------------| | `firstOctave` | Starting octave (negative = larger scale) | | `amplitudes` | List of amplitude weights per octave | **Understanding octaves:** `firstOctave = -7` means the first octave operates at 2⁷ = 128 block scale. Each subsequent octave doubles in frequency (halves in scale). Amplitudes weight each octave's contribution-typically decreasing for higher octaves to add detail without overwhelming the base shape. --- ## Noise Settings Noise settings define the complete terrain generation configuration for a dimension. They specify world bounds, default blocks, the noise router (which density functions control which terrain aspects), and surface rules. Reference: [Noise settings](https://minecraft.wiki/w/Noise_settings) ```kotlin val terrain = dp.noiseSettings("my_terrain") { // Vertical bounds noiseOptions(minY = -64, height = 384, sizeHorizontal = 1, sizeVertical = 2) // Default blocks defaultBlock(Blocks.STONE) {} defaultFluid(Blocks.WATER) { this["level"] = "0" } // Noise router (terrain shaping) // noiseRouter { ... } // Surface rules // surfaceRule = ... // Spawn target // spawnTarget = ... } ``` ### Noise Options ```kotlin noiseOptions( minY = -64, // Minimum Y level height = 384, // Total height (must be multiple of 16) sizeHorizontal = 1, // Horizontal noise size (1, 2, or 4) sizeVertical = 2 // Vertical noise size (1, 2, or 4) ) ``` ### Default Blocks ```kotlin // Solid terrain block defaultBlock(Blocks.STONE) {} // Fluid block with properties defaultFluid(Blocks.WATER) { this["level"] = "0" } ``` ### Noise Router The noise router maps density functions to specific terrain generation roles. Each field controls a different aspect of world generation: Reference: [Noise router](https://minecraft.wiki/w/Noise_settings#Noise_router) ```kotlin noiseRouter { // Core terrain finalDensity = /* density function */ initialDensity = /* density function */ // Aquifers and ore veins barrier = /* density function */ fluidLevelFloodedness = /* density function */ fluidLevelSpread = /* density function */ lava = /* density function */ veinToggle = /* density function */ veinRidged = /* density function */ veinGap = /* density function */ // Biome and erosion continents = /* density function */ erosion = /* density function */ depth = /* density function */ ridges = /* density function */ temperature = /* density function */ vegetation = /* density function */ } ``` ### Surface Rules Surface rules determine which blocks appear on the terrain surface. They're evaluated top-to-bottom, with the first matching rule winning. Conditions can check biome, depth, noise values, and more. Reference: [Surface rule](https://minecraft.wiki/w/Surface_rule) ```kotlin surfaceRule = sequence( condition( biome(Biomes.DESERT), block(Blocks.SAND) ), condition( stoneDepthFloor(offset = 0, addSurfaceDepth = false, secondaryDepthRange = 0), block(Blocks.GRASS_BLOCK) ), block(Blocks.STONE) ) ``` --- ## Complete Example ```kotlin fun DataPack.createCustomTerrain() { // 1) Custom noise definition val hillsNoise = noise("hills_noise") { firstOctave = -5 amplitudes = listOf(1.0, 0.5, 0.25) } // 2) Noise settings for terrain val terrain = noiseSettings("custom_terrain") { noiseOptions(minY = -64, height = 384, sizeHorizontal = 1, sizeVertical = 2) defaultBlock(Blocks.STONE) {} defaultFluid(Blocks.WATER) { this["level"] = "0" } } // 3) Use in dimension val dimType = dimensionType("custom_type") { minY = -64 height = 384 hasSkylight = true } dimension("custom_world", type = dimType) { noiseGenerator( settings = terrain, biomeSource = /* your biome source */ ) } } ``` --- ## Structures --- root: .components.layouts.MarkdownLayout title: Structures nav-title: Structures description: Create structures with template pools, processors, and structure sets using Kore's DSL. keywords: minecraft, datapack, kore, worldgen, structure, template pool, processor, jigsaw date-created: 2026-02-03 date-modified: 2026-02-03 routeOverride: /docs/data-driven/worldgen/structures --- # Structures Structures are large, complex generated features like villages, temples, strongholds, and dungeons. Unlike simple features (trees, ores), structures can span multiple chunks and consist of interconnected pieces assembled using the **jigsaw system**. ## Structure Generation Pipeline Structure generation involves four interconnected components: 1. **Processor list** - Modifies blocks when placing structure pieces (aging, randomization, gravity adjustment) 2. **Template pool** - Defines weighted collections of structure pieces that can connect via jigsaw blocks 3. **Configured structure** - Specifies the structure type, starting pool, biome restrictions, and terrain adaptation 4. **Structure set** - Controls world-scale placement: spacing between structures, clustering, and exclusion zones Structures generate during the `structures_starts` step, before terrain features. This allows terrain to adapt around structures rather than structures cutting through terrain. References: [Structure](https://minecraft.wiki/w/Structure), [Structure definition](https://minecraft.wiki/w/Structure_definition), [Structure set](https://minecraft.wiki/w/Structure_set), [Template pool](https://minecraft.wiki/w/Template_pool), [Processor list](https://minecraft.wiki/w/Processor_list) --- ## Processor List Processor lists transform blocks when structure pieces are placed. They enable effects like aging (cracked bricks, mossy stone), randomization (varied block types), and terrain adaptation (gravity for surface structures). Reference: [Processor list](https://minecraft.wiki/w/Processor_list) ```kotlin val processors = dp.processorList("my_processors") { processors = listOf( // Add processor entries here ) } ``` ### Common Processors | Processor | Description | |--------------------|---------------------------------------------| | `block_rot` | Randomly rotates blocks | | `block_ignore` | Ignores certain blocks during placement | | `block_age` | Ages blocks (cracks, moss) | | `gravity` | Adjusts Y position to terrain | | `rule` | Replaces blocks based on rules | | `protected_blocks` | Prevents certain blocks from being replaced | | `capped` | Limits processor applications | --- ## Template Pool Template pools define weighted collections of structure pieces for jigsaw structures. The jigsaw system connects pieces by matching jigsaw block names, allowing modular structure assembly. Each pool can reference other pools for recursive generation (e.g., village houses connecting to streets connecting to more houses). Reference: [Template pool](https://minecraft.wiki/w/Template_pool) ```kotlin val pool = dp.templatePool("my_pool") { fallback = TemplatePools.Empty elements { // Add weighted template pool entries } } ``` ### Pool Elements ```kotlin elements { // Single piece with weight singlePoolElement( location = "my_namespace:structures/house", projection = Projection.RIGID, processors = myProcessors, weight = 1 ) // Empty element (for spacing) emptyPoolElement(weight = 1) // Feature element featurePoolElement( feature = myPlacedFeature, projection = Projection.TERRAIN_MATCHING, weight = 1 ) // List of elements (all placed together) listPoolElement( elements = listOf(/* ... */), projection = Projection.RIGID, weight = 1 ) } ``` ### Projection Types | Type | Description | |--------------------|--------------------------| | `RIGID` | Maintains original shape | | `TERRAIN_MATCHING` | Adapts to terrain height | --- ## Configured Structure Configured structures define the structure type, starting template pool, biome restrictions, generation step, and terrain adaptation settings. The structure type determines the generation algorithm (jigsaw assembly, single piece, or specialized logic). Reference: [Structure definition](https://minecraft.wiki/w/Structure_definition) ```kotlin dp.structures { // Use the StructuresBuilder DSL } ``` ### Structure Types Common structure types include: - `jigsaw` - Modular structures using template pools - `buried_treasure` - Single buried chest - `desert_pyramid` - Desert temple - `end_city` - End city - `fortress` - Nether fortress - `igloo` - Igloo with optional basement - `jungle_temple` - Jungle temple - `mineshaft` - Underground mineshaft - `monument` - Ocean monument - `nether_fossil` - Nether fossil - `ocean_ruin` - Ocean ruins - `ruined_portal` - Ruined portal - `shipwreck` - Shipwreck - `stronghold` - Stronghold - `swamp_hut` - Witch hut - `woodland_mansion` - Woodland mansion --- ## Structure Set Structure sets control world-scale placement using a grid-based system. **Spacing** defines the grid cell size (average distance), while * *separation** ensures minimum distance between structures. Multiple structures can share a set with weights for mutual exclusion (only one generates per cell). Reference: [Structure set](https://minecraft.wiki/w/Structure_set) ```kotlin val structSet = dp.structureSet("my_structures") { structure(myConfiguredStructure, weight = 1) // Placement type randomSpreadPlacement(spacing = 32, separation = 8) { // Optional: salt, spreadType, etc. } } ``` ### Placement Types #### Random Spread The most common placement type. Divides the world into a grid where each cell may contain one structure at a random position. The `salt` value ensures different structure sets don't align their grids. ```kotlin randomSpreadPlacement( spacing = 32, // Average distance between structures separation = 8 // Minimum distance between structures ) { salt = 12345 // Seed modifier for randomization spreadType = SpreadType.LINEAR // or TRIANGULAR } ``` #### Concentric Rings Places structures in expanding rings around the world origin. Used by strongholds to ensure they're distributed at increasing distances from spawn. Reference: [Structure set - Concentric rings](https://minecraft.wiki/w/Structure_set#concentric_rings) ```kotlin concentricRingsPlacement( distance = 32, spread = 3, count = 128 ) ``` --- ## Complete Example ```kotlin fun DataPack.createCustomVillage() { // 1) Processor list for aging blocks val villageProcessors = processorList("village_processors") { processors = listOf( // Add aging, gravity, etc. ) } // 2) Template pool for houses val housesPool = templatePool("village/houses") { fallback = TemplatePools.Empty elements { singlePoolElement( location = "my_pack:village/house_small", projection = Projection.RIGID, processors = villageProcessors, weight = 3 ) singlePoolElement( location = "my_pack:village/house_large", projection = Projection.RIGID, processors = villageProcessors, weight = 1 ) } } // 3) Start pool (village center) val startPool = templatePool("village/start") { fallback = TemplatePools.Empty elements { singlePoolElement( location = "my_pack:village/center", projection = Projection.RIGID, processors = villageProcessors, weight = 1 ) } } // 4) Configured structure (via structures builder) structures { // Define jigsaw structure referencing startPool } // 5) Structure set for placement structureSet("custom_villages") { // structure(customVillage, weight = 1) randomSpreadPlacement(spacing = 34, separation = 8) { salt = 10387312 } } } ``` --- ## World Presets --- root: .components.layouts.MarkdownLayout title: World Presets nav-title: World Presets description: Create world presets and flat level generator presets with Kore's DSL. keywords: minecraft, datapack, kore, worldgen, world preset, flat, superflat date-created: 2026-02-03 date-modified: 2026-02-03 routeOverride: /docs/data-driven/worldgen/world-presets --- # World Presets World presets define complete world configurations that appear in the "World Type" dropdown during world creation. They specify which dimensions exist and how each generates terrain. Vanilla presets include Default, Superflat, Large Biomes, Amplified, and Single Biome. Custom world presets let you offer players pre-configured world types with your custom dimensions, terrain, and biomes. Reference: [World preset](https://minecraft.wiki/w/World_preset) --- ## World Preset A world preset defines the complete dimension configuration for a world. At minimum, it should include an Overworld dimension, but can also customize or replace the Nether and End, or add entirely new dimensions. ```kotlin dp.worldPreset("my_preset") { dimension(DimensionTypes.OVERWORLD) { type = myDimType // Generator configuration } // Optionally add NETHER, END, or custom dimensions } ``` ### Basic Example ```kotlin dp.worldPreset("custom_world") { // Overworld with custom terrain dimension(DimensionTypes.OVERWORLD) { type = myOverworldType noiseGenerator( settings = myNoiseSettings, biomeSource = multiNoise { /* ... */ } ) } // Standard Nether dimension(DimensionTypes.THE_NETHER) { type = DimensionTypes.THE_NETHER noiseGenerator( settings = NoiseSettings.NETHER, biomeSource = multiNoise { /* ... */ } ) } // Standard End dimension(DimensionTypes.THE_END) { type = DimensionTypes.THE_END noiseGenerator( settings = NoiseSettings.END, biomeSource = theEnd() ) } } ``` ### Custom Dimension in Preset ```kotlin dp.worldPreset("aether_world") { // Replace Overworld with custom dimension dimension(DimensionTypes.OVERWORLD) { type = aetherDimType noiseGenerator( settings = aetherNoise, biomeSource = checkerboard(scale = 3, highlands, forest, shores) ) } } ``` --- ## Flat Level Generator Preset Flat level generator presets appear in the Superflat customization screen, offering quick-select layer configurations. Vanilla presets include Classic Flat, Tunnelers' Dream, Water World, and Redstone Ready. Reference: [Superflat - Presets](https://minecraft.wiki/w/Superflat#Presets) ```kotlin val flatPreset = dp.flatLevelGeneratorPreset("classic_flat") { // Display item in UI // displayItem = Items.GRASS_BLOCK // Flat world settings // layers, biome, structure overrides } ``` ### Flat Generator Layers When using a flat generator in a dimension: ```kotlin dimension("flat_world", type = myDimType) { flatGenerator(biome = Biomes.PLAINS) { layers { layer(Blocks.BEDROCK, height = 1) layer(Blocks.STONE, height = 3) layer(Blocks.DIRT, height = 3) layer(Blocks.GRASS_BLOCK, height = 1) } // structureOverrides = ... } } ``` --- ## Complete Example ```kotlin fun DataPack.createSkylandsPreset() { // 1) Custom dimension type val skyType = dimensionType("skylands_type") { minY = 0 height = 256 hasSkylight = true hasCeiling = false natural = true bedWorks = true hasRaids = true ambientLight = 0.1f } // 2) Noise settings val skyNoise = noiseSettings("skylands_noise") { noiseOptions(minY = 0, height = 256, sizeHorizontal = 2, sizeVertical = 1) defaultBlock(Blocks.STONE) {} defaultFluid(Blocks.WATER) { this["level"] = "0" } } // 3) Biome val skyBiome = biome("skylands_biome") { temperature = 0.5f downfall = 0.5f hasPrecipitation = true effects { skyColor = 0x87CEEB fogColor = 0xC0D8FF waterColor = 0x3F76E4 waterFogColor = 0x050533 } } // 4) World preset worldPreset("skylands") { dimension(DimensionTypes.OVERWORLD) { type = skyType noiseGenerator( settings = skyNoise, biomeSource = fixed(skyBiome) ) } } } ``` --- # Concepts ## Chat Components --- root: .components.layouts.MarkdownLayout title: Chat Components nav-title: Chat Components description: A guide for creating Chat Components in a Minecraft datapack using Kore. keywords: minecraft, datapack, kore, guide, chat-components date-created: 2024-09-05 date-modified: 2026-01-27 routeOverride: /docs/concepts/chat-components --- # Chat Components Chat Components are used to create rich text messages in Minecraft. They can include formatting, interactivity, and nested components. Kore has functions to create and manipulate Chat Components in a datapack.
Note that they always works by groups named `ChatComponents`, whenever you create a chat component, you actually create a `ChatComponents`, and you can chain multiple components together using the `+` operator. Minecraft sometimes does not allow "complex" chat components with data resolving (`score`, `nbt` and `entity` chat components), if you use them, you'll get an empty text component. Simple chat components are inheriting the `SimpleComponent` interface, and you have a `containsOnlySimpleComponents` property to check if a `ChatComponents` only contains simple components. You also have a `containsOnlyText()` function to check if a `ChatComponents` only contains plain text components with no formatting. ### Common Properties - `bold` - Whether the text is bold. - `clickEvent` - The action to perform when the text is clicked. - `color` - The color of the text. - `extra` - Additional components to display after this one (prefer using the `+` operator). - `font` - The font to use. - `hoverEvent` - The action to perform when the text is hovered over. - `insertion` - The text to insert into the chat when the text is shift-clicked. - `italic` - Whether the text is italic. - `obfuscated` - Whether the text is obfuscated. - `shadowColor` - The color of the shadow behind the text. - `strikethrough` - Whether the text is strikethrough. - `text` - The text to display. - `underlined` - Whether the text is underlined. ## PlainTextComponent The `PlainTextComponent` displays simple text with optional formatting such as color and bold.
To create a `PlainTextComponent`, use the `textComponent` function. ### Example ```kotlin val plainText = textComponent("Hello, world!") { color = Color.RED bold = true } ``` In-game output:
![Simple Hello World in bold red](/doc/chat-components/hello-world.png) See how to set custom colors in the [Colors](./colors) article. ### Combined Components Components can be combined using the `+` operator, use the `text` function to create a simple text component and not a `ChatComponents`. ```kotlin val combinedComponents = textComponent("Hello, ") + text("world!") { color = Color.RED bold = true } ``` In-game output:
![Combined Hello World](/doc/chat-components/combined-hello-world.png) > (only the "world!" part is bold and red) ## EntityComponent The `EntityComponent` displays the name of an entity selected by a selector. If multiple entities are found, their names are displayed in the form `Name1, Name2` etc.
The `separator` property can be used to change the separator between the names of the entities.
If no entities are found, the component displays nothing. ### Example ```kotlin val entityComponent = entityComponent(self()) ``` In-game example:
![Hello World of the player](/doc/chat-components/entity.png) ## KeybindComponent The `KeybindComponent` displays a keybind. The keybind is displayed in the player's keybind settings. ### Example ```kotlin val keybindComponent = keybindComponent("key.sprint") ``` In-game example:
![Keybind Component Example](/doc/chat-components/keybind.png) ## NbtComponent The `NbtComponent` displays NBT data from a block, an entity, or a storage. The `interpret` property can be used to interpret the NBT data as a text component, if the parsing fails, nothing is displayed.
The `nbt` property can be used to specify the path to the NBT data.
If `nbt` points to an array, then it will display all the elements joined in the form `Element1, Element2` etc.
The `separator` property can be used to change the separator between the elements of the array. ### Example ```kotlin val nbtComponent = nbtComponent("Health", entity = nearestEntity { type = EntityType.CREEPER }) ``` In-game output:
![NBT Component Example](/doc/chat-components/nbt-health.png) ## ScoreComponent The `ScoreComponent` displays the score of an entity for a specific objective. The `name` property can be used to specify the name of the entity whose score to display, it can be a selector or a literal name (will use the player with that name). It can also be `*` to select the entity seeing the text component.
The `objective` property can be used to specify the name of the objective to display the score of.
A `value` property can be used to specify a fixed value to display regardless of the score. ### Example ```kotlin val scoreComponent = scoreComponent("test") ``` In-game output:
![Score Component Example](/doc/chat-components/score.png) ## TranslatedTextComponent The `TranslatedTextComponent` displays translated text using translation keys. You can also pass arguments to the translation key with the `with` argument, which should be a list of text components or strings.
A `fallback` property can be used to specify a fallback text if the translation key is not found. ### Example ```kotlin val translatedTextComponent = translatedTextComponent("chat.type.text", "Ayfri", "Hello !") ``` In-game output:
![Translated Text Component Example](/doc/chat-components/translation.png) ## Hover Event Hover events display extra information when the text is hovered over, it can be either text, an item, or an entity. Use `showText` to display text, `showItem` to display an item, and `showEntity` to display an entity.
Note that to show an entity, you have to have its UUID as a string. ### Hover Event Example ```kotlin val hoverEventComponent = textComponent("Hover over me!") { hoverEvent { showText("Hello, world!") } } ``` In-game output:
![Hover Event Example](/doc/chat-components/hover.png) ### Hover Item Example ```kotlin val hoverItemComponent = textComponent("Hover over me!") { hoverEvent { showItem(Items.DIAMOND_SWORD { damage(5) }) } } ``` In-game output:
![Hover Event with an Item Example](/doc/chat-components/hover-item.png) ## Click Event Click events perform an action when the text is clicked. The action can be to: - Change the page of the book if reading a book - Copy some text to the clipboard - Open a file - Open a URL - Run a command - Suggest a command (insert the command in the chat but don't run it) ### Click Event Example ```kotlin val clickEventComponent = textComponent("Click me!") { clickEvent { runCommand { say("Hello, world!") } } } ``` ## Object Components Object components render atlas sprites or player skins inside chat. They require the `ObjectTextComponent` family and can be built via `objectComponent` or `playerObjectComponent` depending on the source. ### AtlasObjectTextComponent - `atlas` - The atlas that contains the sprite. Optional when the sprite already resolves to an atlas entry, otherwise provide an explicit `AtlasArgument`. - `sprite` - The `ModelArgument` that identifies the sprite to render and is required. Use `objectComponent` to construct atlas objects, optionally passing an atlas override. ```kotlin val atlasObject = objectComponent( sprite = Textures.Block.COMMAND_BLOCK_BACK, atlas = Atlases.BLOCKS ) ``` In-game output:
![object-command-block.png](/doc/chat-components/object-command-block.png) ### PlayerObjectTextComponent - `hat` - Whether to display the player's hat layer (true/false) or leave it untouched when null. - `player` - A `PlayerProfile` describing the skin whose head should render; provide either a name, UUID, or both plus properties. `playerObjectComponent` accepts a `PlayerProfile`, name, or `UUIDArgument`, and the nested `player` block lets you add `PlayerProperty` estimations. ```kotlin val playerObject = playerObjectComponent("ayfri") { player { property("textures", "base64_encoded_texture_data") } } ``` In-game output:
![player.png](/doc/chat-components/player.png) Notice that there is a shadow on the player's head, you can disable it by setting `shadowColor` to 0. ```kotlin val playerObject = playerObjectComponent("ayfri") { shadowColor = argb(0, 0, 0, 0) } ``` In-game output:
![player-no-shadow.png](/doc/chat-components/player-no-shadow.png) These components respect the same formatting as any other chat component, so you can still chain them, color them, or attach hover and click behaviors. --- ## Colors --- root: .components.layouts.MarkdownLayout title: Colors nav-title: Colors description: Guide to using colors in Kore, including named colors, RGB/ARGB, dye colors, and how different contexts serialize them. keywords: minecraft, kore, colors, rgb, argb, dyes, components, particles date-created: 2025-08-11 date-modified: 2025-08-11 routeOverride: /docs/concepts/colors --- # Overview Kore provides a unified `Color` API that covers three families of colors used by Minecraft: - `FormattingColor` and `BossBarColor` (named colors for chat, UI, teams, etc.) - `RGB` and `ARGB` (numeric colors) - `DyeColors` (the 16 dye colors used by entities and items) For the vanilla reference on color behavior, see the Minecraft Wiki’s Color page (`https://minecraft.wiki/w/Color`). ## Color types in Kore - `Color` (sealed interface): umbrella type accepted by most helpers. - `FormattingColor`: named chat/formatting colors (e.g. `Color.RED`, `Color.AQUA`). - `BossBarColor`: bossbar’s named colors. - `RGB` / `ARGB`: numeric colors. `RGB` is `#rrggbb`, `ARGB` is `#aarrggbb`. - `DyeColors`: 16 dye colors (white, orange, magenta, …, black) for collars, shulkers, sheep, tropical fish, etc. Helpers to create numeric colors: ```kotlin import io.github.ayfri.kore.arguments.colors.* val c1 = color(85, 255, 255) // RGB val c2 = color('#55ffff') // RGB from hex string val c3 = color(0x55ffff) // RGB from decimal val c4 = argb(255, 85, 255, 255) // ARGB val c5 = argb('#ff55ffff') // ARGB from hex string ``` Conversions and utils: ```kotlin val rgb = Color.AQUA.toRGB() // Named/Bossbar/ARGB → RGB val argb = rgb.toARGB(alpha = 200) val mixed = mix(rgb(255, 0, 0), 0.25, rgb(0, 0, 255), 0.75) ``` ## Random colors Kore provides static `random()` helpers on the color classes to simplify testing and procedural generation. You can also use a `Random` instance to generate random colors with a specific seed. These helpers are available on: - **`RGB`**: `RGB.random(random: Random = Random)`: returns a random RGB - **`ARGB`**: `ARGB.random(random: Random = Random, alpha: Boolean = false)`: returns a random ARGB; set `alpha = true` to randomize the alpha channel - **`FormattingColor`**: `FormattingColor.random(random: Random = Random)`: returns a random named formatting color - **`BossBarColor`**: `BossBarColor.random(random: Random = Random)`: returns a random named bossbar color ### Example usage: ```kotlin import kotlin.random.Random import io.github.ayfri.kore.arguments.colors.* import io.github.ayfri.kore.arguments.enums.DyeColors val randomRgb = RGB.random() val randomArgb = ARGB.random(random = Random(12345)) val randomArgbWithAlpha = ARGB.random(alpha = true) val randomFormatting = FormattingColor.random() ``` These helpers were added to make it easy to generate example content, tests, or procedurally-generated visuals. ## Serialization formats by context Different Minecraft systems expect colors in different formats. Kore picks the right format automatically via serializers. - Chat components (`color`, `shadow_color`): string - Named colors emit lowercase names (e.g. `"red"`). - `RGB` emits `"#rrggbb"`; `ARGB` emits `"#aarrggbb"`. - Item components (decimal ints): - `dyedColor(..)`: decimal (or object with `rgb` decimal when tooltip flag is present) [See on GitHub](https://github.com/Ayfri/Kore/tree/master/kore/src/main/kotlin/io/github/ayfri/kore/arguments/components/item/DyedColorComponent.kt#L14) ```kotlin @Serializable(RGB.Companion.ColorAsDecimalSerializer::class) var rgb: RGB, ``` - `mapColor(..)`: decimal [See on GitHub](https://github.com/Ayfri/Kore/tree/master/kore/src/main/kotlin/io/github/ayfri/kore/arguments/components/item/MapColorComponent.kt#L13) ```kotlin InlineSerializer(RGB.Companion.ColorAsDecimalSerializer, MapColorComponent::color) ``` - `potionContents(customColor=..)`: decimal [See on GitHub](https://github.com/Ayfri/Kore/tree/master/kore/src/main/kotlin/io/github/ayfri/kore/arguments/components/item/PotionContentsComponent.kt#L29-L30) ```kotlin @Serializable(RGB.Companion.ColorAsDecimalSerializer::class) var customColor: RGB? = null, ``` - Firework explosion `colors` / `fade_colors`: decimal list [See on GitHub](https://github.com/Ayfri/Kore/tree/master/kore/src/main/kotlin/io/github/ayfri/kore/arguments/components/item/FireworkExplosionComponent.kt#L30-L32) ```kotlin var colors: List<@Serializable(RGB.Companion.ColorAsDecimalSerializer::class) RGB>? = null, @SerialName("fade_colors") var fadeColors: List<@Serializable(RGB.Companion.ColorAsDecimalSerializer::class) RGB>? = null, ``` - Worldgen Biomes (decimal ints): [See on GitHub](https://github.com/Ayfri/Kore/tree/master/kore/src/main/kotlin/io/github/ayfri/kore/features/worldgen/biome/types/BiomeEffects.kt#L12-L17) ```kotlin @Serializable(ColorAsDecimalSerializer::class) var skyColor: Color = color(7907327) @Serializable(ColorAsDecimalSerializer::class) var fogColor: Color = color(12638463) @Serializable(ColorAsDecimalSerializer::class) var waterColor: Color = color(4159204) @Serializable(ColorAsDecimalSerializer::class) var waterFogColor: Color = color(329011) @Serializable(ColorAsDecimalSerializer::class) var grassColor: Color? = null @Serializable(ColorAsDecimalSerializer::class) var foliageColor: Color? = null ``` - Particles: - Command particles (decimal ints): Dust, DustColorTransition, Trail [See on GitHub](https://github.com/Ayfri/Kore/tree/master/kore/src/main/kotlin/io/github/ayfri/kore/commands/particle/types/DustParticleType.kt#L21) ```kotlin var color: @Serializable(ColorAsDecimalSerializer::class) Color, ``` [See on GitHub](https://github.com/Ayfri/Kore/tree/master/kore/src/main/kotlin/io/github/ayfri/kore/commands/particle/types/DustColorTransitionParticleType.kt#L22-L25) ```kotlin var fromColor: @Serializable(ColorAsDecimalSerializer::class) Color, var toColor: @Serializable(ColorAsDecimalSerializer::class) Color, ``` [See on GitHub](https://github.com/Ayfri/Kore/tree/master/kore/src/main/kotlin/io/github/ayfri/kore/commands/particle/types/TrailParticleType.kt#L22) ```kotlin var color: @Serializable(ColorAsDecimalSerializer::class) Color, ``` - Enchantment effect particles (double arrays `[r, g, b]` in 0..1): [See on GitHub](https://github.com/Ayfri/Kore/tree/master/kore/src/main/kotlin/io/github/ayfri/kore/features/enchantments/effects/entity/spawnparticles/types/DustParticleType.kt#L11) ```kotlin var color: @Serializable(ColorAsDoubleArraySerializer::class) Color, ``` [See on GitHub](https://github.com/Ayfri/Kore/tree/master/kore/src/main/kotlin/io/github/ayfri/kore/features/enchantments/effects/entity/spawnparticles/types/DustColorTransitionParticleType.kt#L12-L14) ```kotlin var fromColor: @Serializable(ColorAsDoubleArraySerializer::class) Color, var toColor: @Serializable(ColorAsDoubleArraySerializer::class) Color, ``` [See on GitHub](https://github.com/Ayfri/Kore/tree/master/kore/src/main/kotlin/io/github/ayfri/kore/features/enchantments/effects/entity/spawnparticles/types/EntityEffectParticleType.kt#L11) ```kotlin var color: @Serializable(ColorAsDoubleArraySerializer::class) Color, ``` - UI and commands using named colors (strings): - Teams, Scoreboards, Bossbar: `FormattingColor` / `BossBarColor` [See on GitHub](https://github.com/Ayfri/Kore/tree/master/kore/src/main/kotlin/io/github/ayfri/kore/commands/Teams.kt#L43) ```kotlin fun color(color: FormattingColor) = fn.addLine(..., literal("color"), color) ``` [See on GitHub](https://github.com/Ayfri/Kore/tree/master/kore/src/main/kotlin/io/github/ayfri/kore/commands/BossBar.kt#L57) ```kotlin fun setColor(color: BossBarColor) = fn.addLine(..., literal("color"), color) ``` ## Dye colors and where they’re used `DyeColors` are used for entity variants and certain item/entity data components: - `catCollar(..)`, `wolfCollar(..)`, `sheepColor(..)`, `shulkerColor(..)` [See on GitHub](https://github.com/Ayfri/Kore/tree/master/kore/src/main/kotlin/io/github/ayfri/kore/arguments/components/entity/CatCollar.kt#L11-L22) ```kotlin data class CatCollar(var color: DyeColors) // ... existing code ... fun ComponentsScope.catCollar(color: DyeColors) ``` [See on GitHub](https://github.com/Ayfri/Kore/tree/master/kore/src/main/kotlin/io/github/ayfri/kore/arguments/components/entity/WolfCollar.kt#L11-L22) ```kotlin data class WolfCollar(var color: DyeColors) // ... existing code ... fun ComponentsScope.wolfCollar(color: DyeColors) ``` [See on GitHub](https://github.com/Ayfri/Kore/tree/master/kore/src/main/kotlin/io/github/ayfri/kore/arguments/components/entity/SheepColor.kt#L11-L22) ```kotlin data class SheepColor(var color: DyeColors) // ... existing code ... fun ComponentsScope.sheepColor(color: DyeColors) ``` [See on GitHub](https://github.com/Ayfri/Kore/tree/master/kore/src/main/kotlin/io/github/ayfri/kore/arguments/components/entity/ShulkerColor.kt#L11-L22) ```kotlin data class ShulkerColor(var color: DyeColors) // ... existing code ... fun ComponentsScope.shulkerColor(color: DyeColors) ``` ## Practical examples Chat components (string serialization): ```kotlin import io.github.ayfri.kore.arguments.chatcomponents.textComponent import io.github.ayfri.kore.arguments.colors.Color val title = textComponent('Legendary Sword', Color.AQUA) ``` Dyed leather color (decimal serialization): ```kotlin import io.github.ayfri.kore.generated.Items import io.github.ayfri.kore.arguments.colors.Color val dyedHelmet = Items.LEATHER_HELMET { dyedColor(Color.AQUA) } ``` Map color (decimal serialization): ```kotlin import io.github.ayfri.kore.generated.Items import io.github.ayfri.kore.arguments.colors.rgb val withMapColor = Items.STONE { mapColor(rgb(85, 255, 255)) } ``` Fireworks (decimal lists): ```kotlin import io.github.ayfri.kore.generated.Items import io.github.ayfri.kore.generated.FireworkExplosionShape import io.github.ayfri.kore.arguments.colors.Color val rocket = Items.FIREWORK_ROCKET { fireworks(flightDuration = 1) { explosion(FireworkExplosionShape.BURST) { colors(Color.AQUA) fadeColors(Color.BLACK, Color.WHITE) hasTrail = true hasFlicker = true } } } ``` Biome effects (decimal): ```kotlin import io.github.ayfri.kore.features.worldgen.biome.types.BiomeEffects import io.github.ayfri.kore.arguments.colors.color val effects = BiomeEffects( skyColor = color(7907327), waterColor = color(4159204) ) ``` Particles - Command dust (decimal): ```kotlin import io.github.ayfri.kore.commands.particle.types.Dust import io.github.ayfri.kore.arguments.colors.Color val p = Dust(color = Color.RED, scale = 1.0) ``` - Enchantment dust (double array): ```kotlin import io.github.ayfri.kore.features.enchantments.effects.entity.spawnparticles.types.DustParticleType import io.github.ayfri.kore.generated.arguments.types.ParticleTypeArgument import io.github.ayfri.kore.arguments.colors.rgb val enchantDust = DustParticleType( type = ParticleTypeArgument('minecraft:dust'), color = rgb(255, 0, 0) ) ``` Entity variant dye usage: ```kotlin import io.github.ayfri.kore.generated.Items import io.github.ayfri.kore.arguments.enums.DyeColors val cat = Items.CAT_SPAWN_EGG { catCollar(DyeColors.RED) } ``` ## Notes - Passing `Color` to component helpers that use decimal or double-array formats is safe: Kore converts automatically via `toRGB()`. - Use `DyeColors` when the game mechanic expects a dye color (collars, sheep, shulkers, tropical fish), and `FormattingColor`/ `BossBarColor` for chat/UI tints. ## Further reading - Minecraft Wiki - Color: [`https://minecraft.wiki/w/Color`](https://minecraft.wiki/w/Color) --- ## Components --- root: .components.layouts.MarkdownLayout title: Components nav-title: Components description: A guide for using components in Minecraft with Kore. keywords: minecraft, datapack, kore, guide, components date-created: 2024-01-08 date-modified: 2026-02-03 routeOverride: /docs/concepts/components --- In Minecraft, data components are structured key-value properties used to define and store behavior and attributes. They are attached to different things: - Item components: properties that live on item stacks (e.g., `enchantments`, `food`, `attribute_modifiers`). They affect how items behave in inventories, commands, containers, etc. - Entity variant components: properties exposed as components for certain entity variants when represented as items or spawn eggs (e.g., `wolf/variant`, `cat/collar`). These follow the same component mechanics but target entity-specific customization. This page focuses on using item components with Kore. For the vanilla reference and exhaustive definitions, see the Minecraft Wiki’s Data component format ( `https://minecraft.wiki/w/Data_component_format`). The Kore library provides a comprehensive and user-friendly way to work with these components, enabling you to create custom items with ease. This article will guide you through the process of using components with Kore, showcasing examples and best practices. ## Creating Custom Items with Components Let's dive into creating custom items with various components using Kore. Below are examples of how to define and manipulate item properties such as attribute modifiers, enchantments, and more. ### Attribute Modifiers Attribute modifiers allow you to alter the attributes of an item, such as increasing damage or changing the scale. Here's how to define a stone sword with an attribute modifier using Kore: ```kotlin import io.github.ayfri.kore.arguments.types.literals.randomUUID import io.github.ayfri.kore.commands.AttributeModifierOperation import io.github.ayfri.kore.generated.Items import io.github.ayfri.kore.generated.Attributes val uuid = randomUUID() val attributeModifiersTest = Items.STONE_SWORD { attributeModifiers { modifier( type = Attributes.SCALE, amount = 1.0, name = "Big!", operation = AttributeModifierOperation.ADD_VALUE, uuid = uuid, ) } } ``` ### Enchantments You can add enchantments to items to give them special abilities. Here’s an example of adding the Sharpness enchantment to a stone sword: ```kotlin import io.github.ayfri.kore.generated.Enchantments val enchantmentsTest = Items.STONE_SWORD { enchantments(mapOf(Enchantments.SHARPNESS to 5)) } ``` Check out the [Enchantments](./enchantments) article for more information on how to use enchantments with Kore. ### Custom Names and Lore Custom names and lore can be added to items to give them unique identifiers and background stories: ```kotlin import io.github.ayfri.kore.arguments.chatcomponents.textComponent import io.github.ayfri.kore.arguments.colors.Color val customNameTest = Items.STONE_SWORD { customName(textComponent("Legendary Sword", Color.AQUA)) } ``` ### Fireworks You can define the properties of fireworks, including the shape and colors of the explosions: ```kotlin import io.github.ayfri.kore.generated.FireworkExplosionShape import io.github.ayfri.kore.arguments.colors.Color val fireworksTest = Items.FIREWORK_ROCKET { fireworks(flightDuration = 1) { explosion(FireworkExplosionShape.BURST) { colors(Color.AQUA) fadeColors(Color.BLACK, Color.WHITE) hasTrail = true hasFlicker = true } } } ``` See how to set custom colors in the [Colors](./colors) article. ### Custom Block Data You can define custom properties for blocks using block entity data. Here's an example of adding custom data to a bee nest block: ```kotlin import io.github.ayfri.kore.generated.Blocks import io.github.ayfri.kore.generated.Items val blockEntityDataTest = Items.BEE_NEST { blockEntityData(Blocks.BEE_NEST) { this["test"] = "test" } } ``` ### Profile The profile component can be either a player profile or a texture-based profile. #### Player Profile A player profile uses a player's name or UUID: ```kotlin Items.PLAYER_HEAD { playerProfile("Notch") } ``` #### Texture Profile A texture profile allows you to specify textures and models: ```kotlin Items.PLAYER_HEAD { textureProfile(texture = "tex") { model = MannequinModel.SLIM } } ``` ### Recipes result with components You can define recipes with components as well. Here's an example of crafting a custom enchanted golden apple using a shaped recipe: ```kotlin recipes { craftingShaped("enchanted_golden_apple") { pattern( "GGG", "GAG", "GGG" ) key("G", Items.GOLD_BLOCK) key("A", Items.APPLE) result(Items.ENCHANTED_GOLDEN_APPLE { food( nutrition = 10, saturation = 5.0f, ) { effect( probability = 1f, id = Effects.REGENERATION, duration = 40, amplifier = 1, ambient = true, showParticles = true, showIcon = true ) } }) } } ``` ## Example Usage To give yourself an item with custom components using the `/give` command, you can define the item and its components as shown in the following example: ```kotlin import io.github.ayfri.kore.generated.Items import io.github.ayfri.kore.utils.set // Define the item with a custom name val customStone = Items.STONE { fireResistant() customName(textComponent("Special Stone", Color.AQUA)) rarity(Rarities.EPIC) lore( textComponent("A stone with special properties.", Color.GRAY) + text("Use it wisely!", Color.GRAY) ) } // Use the /give command to give the item to yourself give(self(), customStone) ``` This example creates a custom stone item with a special name "Special Stone" in aqua color and gives it to the player using the `/give` command. ### Full list of Item components Below is an alphabetical list of all item component helpers available in Kore. The names match the DSL functions you call inside an `Items.* { }` builder. | Helper | Description | |--------------------------------------|---------------------------------------------------------------------------------------------------| | `attributeModifiers(..)` | Modifies entity attributes (e.g., attack damage, speed, armor) when the item is equipped or held. | | `bannerPatterns(..)` | Defines the layered patterns displayed on a banner or shield. | | `baseColor(..)` | Sets the base color of a banner before patterns are applied. | | `bees { .. }` | Stores bee entities inside a beehive or bee nest item. | | `blockEntityData(..)` | Attaches custom NBT data to a block entity when the item is placed. | | `blocksAttacks(..)` | Configures how the item blocks incoming attacks when used (like a shield). | | `blockState(..)` | Sets block state properties (e.g., facing, powered) when the item is placed. | | `breakSound(..)` | Specifies the sound played when the item breaks from durability loss. | | `bucketEntityData(..)` | Stores entity data for mobs captured in buckets (e.g., fish, axolotl). | | `bundleContents(..)` | Defines the items stored inside a bundle. | | `canBreak(..)` | Restricts which blocks this item can break in Adventure mode. | | `canPlaceOn(..)` | Restricts which blocks this item can be placed on in Adventure mode. | | `chargedProjectiles(..)` | Stores projectiles loaded into a crossbow. | | `consumable(..) { .. }` | Makes the item consumable with configurable eating time, animation, sound, and effects. | | `container(..)` | Stores items inside a container item (e.g., shulker box). | | `containerLoot(..)` | References a loot table to generate container contents when opened. | | `customData(..)` | Attaches arbitrary custom NBT data for use by datapacks or mods. | | `customModelData(..)` | Provides numeric values for custom item model selection in resource packs. | | `customName(..)` | Sets a custom display name for the item (supports text components). | | `damage(..)` | Sets the current damage/durability consumed on a damageable item. | | `damageResistant(..)` | Makes the item entity resistant to specific damage types (e.g., fire, explosions). | | `damageType(..)` | Specifies the damage type dealt when attacking with this item. | | `deathProtection(..)` | Prevents death and applies effects when the holder would die (like a totem). | | `debugStickState(..)` | Stores the selected block state property for the debug stick per block type. | | `dyedColor(..)` | Sets the dye color for leather armor or other dyeable items. | | `enchantable(..)` | Defines the enchantability value affecting enchantment quality at enchanting tables. | | `enchantmentGlintOverride(..)` | Forces the enchantment glint on or off regardless of enchantments. | | `enchantments(..)` | Applies enchantments with their levels to the item. | | `entityData(..)` | Stores entity NBT data for spawn eggs or items that spawn entities. | | `equippable(..)` | Configures equipment slot, sounds, and model when the item is worn. | | `fireworkExplosion(..)` | Defines a single firework star explosion shape, colors, and effects. | | `fireworks(..)` | Configures firework rocket flight duration and explosion effects. | | `food(..)` | Makes the item edible with nutrition, saturation, and optional effects. | | `glider()` | Enables elytra-like gliding when equipped in the chest slot. | | `instrument(..)` | Specifies the goat horn sound variant when the item is used. | | `intangibleProjectile()` | Makes projectiles from this item pass through entities without collision. | | `itemModel(..)` | Overrides the item's model with a custom model resource location. | | `itemName(..)` | Sets the item's base name (different from custom name; not italicized). | | `jukeboxPlayable(..)` | Allows the item to be played in a jukebox with a specified music disc track. | | `kineticWeapon(..) { .. }` | Configures kinetic weapon properties for mounted combat (reach, damage multiplier, conditions). | | `lock(..)` | Requires a matching item predicate (key) to open this container. | | `lodestoneTarget(..)` | Makes a compass point to specific coordinates in a dimension. | | `lore(..)` | Adds tooltip lines below the item name for descriptions or flavor text. | | `mapColor(..)` | Sets the color tint for filled map item textures. | | `mapDecorations(..)` | Adds custom icons/markers displayed on a filled map. | | `mapId(..)` | Links the item to a specific map data ID for filled maps. | | `maxDamage(..)` | Sets the maximum durability before the item breaks. | | `maxStackSize(..)` | Overrides how many items can stack in a single inventory slot (1-99). | | `minimumAttackCharge(..)` | Sets the minimum attack charge (0.0-1.0) required for full damage. | | `noteBlockSound(..)` | Specifies the sound a note block plays when this player head is above it. | | `ominousBottleAmplifier(..)` | Sets the Bad Omen effect amplifier (0-4) when consuming an ominous bottle. | | `piercingWeapon(..) { .. }` | Configures piercing weapon properties (reach, knockback, dismount behavior). | | `playerProfile(..)` | Sets the player skin displayed on a player head item. | | `potDecorations(..)` | Defines the pottery sherds or bricks on each face of a decorated pot. | | `potionContents(..)` | Configures potion color, effects, and custom potion mixtures. | | `potionDurationScale(..)` | Multiplies the duration of potion effects from this item. | | `providesBannerPatterns(..)` | Registers this item as a banner pattern source for the loom. | | `providesTrimMaterial(..)` | Registers this item as an armor trim material for the smithing table. | | `rarity(..)` | Sets the item name color tier (common, uncommon, rare, epic). | | `recipes(..)` | Unlocks specified recipes when this knowledge book is used. | | `repairable(..)` | Defines which items can repair this item on an anvil. | | `repairCost(..)` | Sets the anvil repair cost penalty for combining or renaming. | | `storedEnchantments(..)` | Stores enchantments in an enchanted book for anvil application. | | `suspiciousStewEffectsComponent(..)` | Defines the status effects applied when consuming suspicious stew. | | `swingAnimation(..)` | Configures the swing animation type (none, stab, whack) and duration. | | `tool { .. }` | Configures mining speeds, suitable blocks, and durability cost for tools. | | `tooltipDisplay(..)` | Controls which tooltip sections are shown or hidden. | | `tooltipStyle(..)` | Applies a custom tooltip background/border style from a resource pack. | | `trim(..)` | Applies an armor trim pattern and material to armor items. | | `unbreakable()` | Prevents the item from taking durability damage. | | `useCooldown(..)` | Applies a cooldown period after using this item. | | `useEffects(..)` | Configures use effects like allowing sprinting and speed multiplier while using. | | `useRemainder(..)` | Specifies an item left behind after this item is fully consumed. | | `weapon(..)` | Configures melee weapon properties like damage and attack speed. | | `writableBookContent(..)` | Stores editable pages in a book and quill. | | `writtenBookContent(..)` | Stores signed book content including title, author, and pages. | ## Works great with Inventory Manager If you build rich items with components and want to enforce them in player GUIs or chest slots, pair them with the [Inventory Manager](./helpers/inventory-manager). It lets you keep specific items in slots, react to takes, and clean up other slots while preserving all component data. ## Patch items When you need to patch components on existing stacks (set name/lore, toggle tooltips, edit container contents, etc.) at runtime, use [Item Modifiers](./item-modifiers). Kore maps the vanilla functions like `set_components`, `set_contents`, `set_fireworks`, and more. ## Custom Component You can create custom components by extending the `CustomComponent` class. Here's an example of a custom component that adds a custom attribute to an item: ```kotlin package your.package import io.github.ayfri.kore.arguments.components.ComponentsScope import io.github.ayfri.kore.arguments.components.types.CustomComponent import io.github.ayfri.kore.arguments.types.resources.FunctionArgument import io.github.ayfri.kore.arguments.types.resources.SoundArgument import io.github.ayfri.kore.utils.nbt import kotlinx.serialization.Serializable import kotlinx.serialization.SerialName @Serializable data class UseComponent( var function: FunctionArgument, @SerialName("durability_damages") // properties aren't renamed to snake_case because of a limitation in KNBT library var durabilityDamages: Int? = null, // optional property, equals to 0 in Minecraft var cooldown: Float? = null, // optional property, equals to 0 in Minecraft var consume: Boolean? = null, // optional property, equals to false in Minecraft var sound: SoundArgument? = null, // optional property, equals to null in Minecraft ) : CustomComponent( nbt { this["function"] = function this["damage"] = damage this["cooldown"] = cooldown this["consume"] = consume this["sound"] = sound } ) fun ComponentsScope.use( function: FunctionArgument, damage: Int? = null, cooldown: Float? = null, consume: Boolean? = null, sound: SoundArgument? = null, ) = apply { this["use_component"] = UseComponent(function, damage, cooldown, consume, sound) } ``` And here's how you can use this custom component in an item definition: ```kotlin import io.github.ayfri.kore.generated.Items import io.github.ayfri.kore.generated.Sounds import your.package.use val customItem = Items.DIAMOND_SWORD { val myFunction = function("use_weapon") { // Your function code here. } use( function = myFunction, durabilityDamages = 4, cooldown = 1.5f, sound = Sounds.Entity.Player.Attack.CRIT1 ) } // Result: minecraft:diamond_sword[use_component ={ function:"datapack:use_weapon", damage:4, cooldown:1.5f, sound:"entity/player/attack/crit1" }] ``` ## Entity Variant Components (25w04a+) > *Introduced in snapshot [25w04a](https://www.minecraft.net/en-us/article/minecraft-snapshot-25w04a)* > > Entity variants such as axolotl colours, cat collars or tropical-fish patterns are now exposed as **data components ** and can be used on entities, spawn-egg items, mob buckets and paintings. This replaces the old `type_specific` NBT fields. Kore ships dedicated helpers for each of these components. You can attach them to an `Items.*` builder the exact same way you attach any other component: ```kotlin import io.github.ayfri.kore.generated.Items import io.github.ayfri.kore.arguments.enums.* // Axolotl bucket with the blue variant val blueAxolotlBucket = Items.AXOLOTL_BUCKET { axolotlVariant(AxolotlVariants.BLUE) } // Cat spawn-egg with a red collar val redCollarCat = Items.CAT_SPAWN_EGG { catCollar(DyeColors.RED) } // Painting item selecting the "kebab" variant (namespace implied) val kebabPainting = Items.PAINTING { paintingVariant(PaintingVariants.KEBAB) } ``` These components can also be queried inside predicates: ```kotlin predicate("only_blue_axolotls") { entityProperties { components { axolotlVariant(AxolotlVariants.BLUE) } } } ``` The full list of variant helpers currently included in Kore is: - `axolotlVariant(..)` - `catCollar(..)` / `catVariant(..)` - `foxVariant(..)` - `frogVariant(..)` - `horseVariant(..)` - `llamaVariant(..)` - `mooshroomVariant(..)` - `paintingVariant(..)` - `parrotVariant(..)` - `pigVariant(..)` - `rabbitVariant(..)` - `salmonSize(..)` - `sheepColor(..)` - `shulkerColor(..)` - `tropicalFishBaseColor(..)` / `tropicalFishPattern(..)` / `tropicalFishPatternColor(..)` - `villagerVariant(..)` - `wolfCollar(..)` / `wolfVariant(..)` They follow the exact same naming and DSL pattern you already know: ```kotlin fun ComponentsScope.wolfVariant(variant: WolfVariants) { /*…*/ } ``` Because the logic lives in regular data components, you automatically get: • Compatibility with `itemStack` / `Items.*` DSL • Predicate support through `components {}` • Correct serialisation back to the vanilla command-/NBT-syntax Feel free to mix several variant components on the same `ComponentsScope`: ```kotlin Items.WOLF_SPAWN_EGG { wolfCollar(DyeColors.BLACK) wolfVariant(WolfVariants.SNOWY) } ``` ## Component Matchers & Item Predicates Kore provides powerful tools for matching and filtering items based on their components. This is useful in predicates, execute conditions, and loot tables. ### Complete Example: Custom Tool Upgrade System Here's a practical example showing how to use item predicates to create a tool upgrade system that detects enchanted, damaged tools and replaces them with upgraded versions: ```kotlin dataPack("tool_upgrades") { // Predicate to find diamond swords that need upgrading predicate("upgradeable_sword") { matchTool { items(Items.DIAMOND_SWORD) predicates { // Must have Sharpness enchantment enchantments { enchantment(Enchantments.SHARPNESS, level = rangeOrInt(1..4)) } // Must be damaged (durability used) damage { damage = rangeOrInt(1..1000) } } } } // Function to check player's held item and upgrade it function("check_upgrade") { // Check if holding an upgradeable sword execute { ifCondition { items( self(), ItemSlot.WEAPON_MAINHAND, Items.DIAMOND_SWORD.predicate { subPredicates { enchantments { enchantment(Enchantments.SHARPNESS, level = rangeOrInt(3..4)) } } } ) } run { // Replace with netherite sword keeping enchantments items.modify(self(), ItemSlot.WEAPON_MAINHAND, itemModifier("upgrade_to_netherite")) tellraw(self(), textComponent("Your sword has been upgraded!", Color.GOLD)) } } } // Clear specific items from inventory using predicates function("clear_broken_tools") { // Clear any tool with 1 durability left clear(allPlayers(), itemPredicate { subPredicates { damage { durability = rangeOrInt(1) } } }) } // Give reward only if player has specific item combination function("check_collection") { execute { // Check for a goat horn (any variant) ifCondition { items( self(), ItemSlot.INVENTORY, itemPredicate { isPresent(ItemComponentTypes.INSTRUMENT) } ) } // Check for enchanted book with Mending ifCondition { items( self(), ItemSlot.INVENTORY, Items.ENCHANTED_BOOK.predicate { subPredicates { storedEnchantments { enchantment(Enchantments.MENDING) } } } ) } run { give(self(), Items.NETHER_STAR) } } } } ``` ### Item Predicates Item predicates let you filter items by their components using the command syntax `[predicate]`: ```kotlin import io.github.ayfri.kore.arguments.components.* import io.github.ayfri.kore.arguments.components.item.* import io.github.ayfri.kore.generated.Items import io.github.ayfri.kore.generated.ItemComponentTypes // Match items with specific component values val damagedSword = Items.DIAMOND_SWORD.predicate { damage(10) } // Result: minecraft:diamond_sword[damage=10] // Match any item with a component present (existence check) val hasInstrument = itemPredicate { isPresent(ItemComponentTypes.INSTRUMENT) } // Result: *[instrument] // Partial matching with ~ syntax val customDataMatch = Items.STONE.predicate { customData { this["myKey"] = "myValue" } partial(ItemComponentTypes.CUSTOM_DATA) } // Result: minecraft:stone[custom_data~{myKey:"myValue"}] // Negated predicates (component must NOT have this value) val notDamaged = Items.DIAMOND_SWORD.predicate { !damage(0) } // Result: minecraft:diamond_sword[!damage=0] // Multiple alternatives with OR val multipleValues = Items.STONE.predicate { damage(1) or damage(2) or damage(3) } // Result: minecraft:stone[damage=1|damage=2|damage=3] // Count predicate val stackOf10 = Items.DIAMOND.predicate { count(10) } // Result: minecraft:diamond[count=10] ``` ### Component Matchers (Sub-Predicates) For more complex matching logic, use `subPredicates` with component matchers. These serialize to JSON format for use in predicate files: ```kotlin import io.github.ayfri.kore.features.predicates.sub.item.ItemStackSubPredicates import io.github.ayfri.kore.arguments.components.matchers.* import io.github.ayfri.kore.arguments.numbers.ranges.rangeOrInt val subPredicate = ItemStackSubPredicates().apply { // Match damage component with range damage { durability = rangeOrInt(1..100) damage = rangeOrInt(0..10) } // Match enchantments enchantments { enchantment(Enchantments.SHARPNESS, level = 3) } // Match potion contents potionContents(Effects.SPEED, Effects.STRENGTH) } ``` ### Existence Checks You can check if a component exists on an item without matching a specific value: ```kotlin // In item predicates (command form) val hasInstrument = itemPredicate { isPresent(ItemComponentTypes.INSTRUMENT) } // Result: *[instrument] // In sub-predicates (JSON form for predicate files) val existsCheck = ItemStackSubPredicates().apply { exists(ItemComponentTypes.INSTRUMENT) } // Result: {"minecraft:instrument": {}} // Multiple existence checks val multipleExists = ItemStackSubPredicates().apply { exists(ItemComponentTypes.INSTRUMENT) exists(ItemComponentTypes.DAMAGE) } // Result: {"minecraft:instrument": {}, "minecraft:damage": {}} ``` ### Available Component Matchers | Matcher | Description | |---------------------------|------------------------------------------------| | `attributeModifiers { }` | Match attribute modifier properties | | `bundlerContents { }` | Match bundle contents | | `container { }` | Match container slot contents | | `customData { }` | Match custom NBT data | | `damage { }` | Match damage/durability values | | `enchantments { }` | Match enchantment types and levels | | `exists(component)` | Check if component exists (empty `{}` matcher) | | `fireworkExplosion { }` | Match firework star properties | | `fireworks { }` | Match firework rocket properties | | `jukeboxPlayable { }` | Match jukebox song | | `potionContents(..)` | Match potion effects | | `storedEnchantments { }` | Match stored enchantments (enchanted books) | | `trim { }` | Match armor trim pattern/material | | `writableBookContent { }` | Match book pages | | `writtenBookContent { }` | Match signed book content | ## Conclusion Components are a powerful tool for customizing Minecraft objects, and the Kore library makes it easier than ever to work with these components programmatically. Whether you're adding custom attributes, enchantments, or creating complex items with multiple components, Kore provides a robust and intuitive API for enhancing your Minecraft experience. By following the examples and practices outlined in this article, you can leverage the full potential of components in your Minecraft projects, creating richer and more engaging content for players. Happy crafting! ## See Also - [Predicates](../data-driven/predicates) - Use components in predicate conditions - [Item Modifiers](../data-driven/item-modifiers) - Patch components at runtime - [Recipes](../data-driven/recipes) - Use components in recipe results - [Inventory Manager](../helpers/inventory-manager) - Enforce component-rich items in slots ### External Resources - [Minecraft Wiki: Data component format](https://minecraft.wiki/w/Data_component_format) - Official component reference --- ## Scoreboards --- root: .components.layouts.MarkdownLayout title: Scoreboards nav-title: Scoreboards description: A guide for managing scoreboards in a Minecraft datapack using Kore. keywords: minecraft, datapack, kore, guide, scoreboards date-created: 2024-04-06 date-modified: 2026-02-03 routeOverride: /docs/concepts/scoreboards --- # Scoreboards Scoreboards track numeric values for players and entities. They're essential for game mechanics, timers, and storing data. For the full scoreboard command reference, see [Commands](../commands/commands#scoreboard-command). You can manage scoreboards with the `scoreboard` command: ```kotlin scoreboard.objectives.add("my_objective", ScoreboardCriteria.DUMMY) ``` ## Creating objectives You have multiple forms of the `scoreboard` command: ```kotlin scoreboard { objectives { add("my_objective", ScoreboardCriteria.DUMMY) // this form lets you manage multiple objectives at once } } scoreboard { objective("my_objective") { add(ScoreboardCriteria.DUMMY) // this form lets you manage a single objective } } ``` ## Managing objectives You can add, remove, set display name, set display slot, set render type of objectives: ```kotlin scoreboard { objective("my_objective") { add(ScoreboardCriteria.DUMMY, displayName = textComponent("My Objective", Color.GOLD)) setDisplaySlot(DisplaySlots.sidebar) setRenderType(RenderType.INTEGER) } } ``` ## Manage players You can manage players with the `players` block: ```kotlin scoreboard { players { add(allPlayers(), "my_objective", 1) remove(self(), "my_objective", 5) reset(self(), "my_objective") set(self(), "my_objective", 10) operation(self(), "my_objective", Operation.ADD, self(), "my_objective") } player(self()) { add("my_objective", 1) remove("my_objective", 5) reset("my_objective") set("my_objective", 10) operation("my_objective", Operation.ADD, self(), "my_objective") } } ``` You can also manage an objective for multiple selectors at once: ```kotlin scoreboard { players { objective("my_objective") { add(self(), 1) remove(self(), 5) reset(self()) set(self(), 10) operation(self(), Operation.ADD, self(), objective) } } } ``` Or also manage an objective for a single selector: ```kotlin scoreboard { player(self()) { objective("my_objective") { add(1) remove(5) reset() set(10) operation(Operation.ADD, self(), objective) } } } ``` These methods offer a more readable way to manage objectives, and avoid repetition operations invoking multiple times the same selector/objective. ## Scoreboard Displays Scoreboard Displays are a new helper that let you manage right sidebar displays, like on servers. You can create a display with the `scoreboardDisplay` function: ```kotlin scoreboardDisplay("my_display") { displayName = textComponent("My Display", Color.GOLD) setLine(0, textComponent("Line 1", Color.AQUA)) appendLine(textComponent("Line 2", Color.AQUA)) emptyLine() appendLine("Line 4", Color.AQUA) appendLine(textComponent("Line 2", Color.AQUA)) { createIf { // this line will only be created if the condition is true, this is executed in an `execute if` block predicate("stonks") } } } ``` You can also change the line numbers display: ```kotlin scoreboardDisplay("my_display") { decreasing = false startingScore = 0 } ``` #### New since 1.20.3 You can now hide the values of the lines: ```kotlin scoreboardDisplay("my_display") { appendLine("a") { hideValue = true // this will hide the value of the line } appendLine("b") hideValues() // this will hide the values of all lines // you can also provide a range of indices for the lines to hide } ``` Feel free to add feedback if you have any idea to improve this or to use other features from the new `scoreboard players display numberformat` subcommand. ### Resetting Scoreboard Displays You can reset all scoreboards with the `resetAll` function: ```kotlin ScoreboardDisplay.resetAll() ``` ### Limitations Scoreboard Displays are displayed the same way to everyone, so you can't have different displays for different players. You can at least have different displays for different team colors, but that's all (so there's a property to set the display slot). The sidebar is limited to 15 lines, so you can't have more than 15 lines in a display. ### How it works Scoreboard Displays are generated using fake players and teams, it will create teams with randomized numbers as name to avoid conflicts. Each line = 1 team, and each team has a suffix with the line text, then a fake player is added to the team with the score of the line number. For dynamic animations of displays, there aren't any solution for that currently. The only way to do that is to use a binary tree of functions, checking the score of the player between 0 and the middle of the maximum score, then between the middle and the maximum, and split the function in two, and so on. Then, when you arrive to the last function, you can call the `setLine` function to set the line text. And you repeat this for each line. If you have a better solution, maybe using macros, feel free to create functions for that and create a pull request. #### New since 1.20.3 Now scoreboard displays can be created more easily as you can now customize the display of each player as a text component. No teams are created anymore, and the display is generated using the `scoreboard players display name` command, achieving the same result. --- # Helpers ## Display Entities --- root: .components.layouts.MarkdownLayout title: Display Entities nav-title: Display Entities description: A guide for creating Display Entities in the world. keywords: minecraft, datapack, kore, guide, display-entities date-created: 2024-04-06 date-modified: 2024-04-06 routeOverride: /docs/helpers/display-entities --- # Display Entities ## Entity Displays Entity displays are used to display blocks/items/text in the world. You can define multiple properties for the display, such as transformation, billboard mode, shadow etc. ```kotlin val entityDisplay = blockDisplay { blockState(Blocks.GRASS_BLOCK) { properties { this["snowy"] = true } } transformation { leftRotation { quaternionNormalized(0.0, 0.0, 0.0, 1.0) } scale = vec3(2.0) translation { y = 2.0 } } billboardMode = BillboardMode.CENTER shadowRadius = 0.5f } summon(entity = entityDisplay.entityType, pos = vec3(0, 0, 0), nbt = entityDisplay.toNbt()) // will summon a grass block with snow on top, scaled by 2, rotated by 0 degrees and translated by 2 blocks on the y axis at the position 0, 0, 0 ``` ## Block Displays Block displays are used to display blocks in the world. They are created by calling `blockDiplay()` DSL. ```kotlin val blockDisplay = blockDisplay { blockState(Blocks.GRASS_BLOCK) { properties { this["snowy"] = true } } } ``` ## Item Displays Item displays are used to display items in the world. They are created by calling `itemDisplay()` DSL. ```kotlin val itemDisplay = itemDisplay { item(Items.DIAMOND_SWORD) { name = textComponent("test") enchantments { Enchantments.SHARPNESS at 1 Enchantments.UNBREAKING at 3 } modifiers { modifier(Attributes.ATTACK_DAMAGE, 1.0, AttributeModifierOperation.ADD) } } } ``` ## Text Displays Text displays are used to display text in the world. They are created by calling `textDisplay()` DSL. ```kotlin val textDisplay = textDisplay { text("test", Color.RED) { bold = true } } ``` ## Transformations Transformations are used to modify the translation, left/right rotations and scale of displays. They are created by calling `transformation` DSL. You can also apply directly matrix transformations and use quaternions, axis angles or use Euler angles for rotations. ```kotlin transformation { leftRotation { quaternionNormalized(0.0, 0.0, 0.0, 1.0) } scale = vec3(2.0) translation { y = 2.0 } } ``` ## Interpolations You can convert your display entity into an "interpolable" display entity by calling `interpolable()` on it. This will allow you to interpolate between the current transformation and the target transformation in a given time. ```kotlin val interpolableEntityDisplay = blockDisplay { blockState(Blocks.STONE_BLOCK) }.interpolable(position = vec3(0, 0, 0)) interpolableEntityDisplay.summon() interpolableEntityDisplay.interpolateTo(duration = 2.seconds) { translation { y = 2.0 } } ``` I will later add more methods and maybe a complete DSL for making full animations. --- ## Inventory Manager --- root: .components.layouts.MarkdownLayout title: Inventory Manager nav-title: Inventory Manager description: Listen to slot events and control containers (players, blocks) with Kore's Inventory Manager. keywords: minecraft, datapack, kore, inventory, container, slots, events, gui date-created: 2025-08-11 date-modified: 2025-08-11 routeOverride: /docs/helpers/inventory-manager --- # Inventory Manager Kore’s Inventory Manager lets you declaratively control inventories on entities or blocks and react to slot events. - Manage items in any `ContainerArgument` (players, entities, or block containers). - Register slot listeners that fire when an item is taken from a slot. - Keep a slot populated, clear other slots, or run custom logic every tick. - Auto-generate the required load/tick functions and minimal scoreboards to drive the listeners. ## Quick start ```kotlin import io.github.ayfri.kore.arguments.types.literals.nearestPlayer import io.github.ayfri.kore.arguments.colors.Color import io.github.ayfri.kore.arguments.chatcomponents.textComponent import io.github.ayfri.kore.commands.TitleLocation import io.github.ayfri.kore.generated.Items import io.github.ayfri.kore.helpers.inventorymanager.inventoryManager function("inventory_demo") { val playerInv = inventoryManager(nearestPlayer()) playerInv.slotEvent(HOTBAR[0], Items.NETHER_STAR { this["display"] = nbt { this["Name"] = textComponent("Do not move me", color = Color.RED).toJsonString() } }) { onTake { title(self(), TitleLocation.ACTIONBAR, textComponent("Stop taking me!", color = Color.RED)) } duringTake { setItemInSlot() } onTick { clearAllItemsNotInSlot(); killAllItemsNotInSlot() } setItemInSlot() // seed the slot once } // Start listeners for this manager playerInv.generateSlotsListeners() } ``` Tip: Use the builder variant to both declare listeners and auto-generate them in one go: ```kotlin inventoryManager(nearestPlayer()) { slotEvent(HOTBAR[0], Items.DIAMOND) { setItemInSlot() } generateSlotsListeners() } ``` ## Block containers You can target block inventories as well by passing a `Vec3` and (optionally) placing a container block first: ```kotlin val chestPos = vec3(0, -59, 0) inventoryManager(chestPos) { setBlock(Blocks.CHEST) slotEvent(CONTAINER[0], Items.DIAMOND_SWORD) { onTake { tellraw(allPlayers(), text("You took the sword!", Color.RED)) } duringTake { setItemInSlot() } onTick { clearAllItemsNotInSlot(); killAllItemsNotInSlot() } setItemInSlot() } generateSlotsListeners() } ``` ## API overview - `inventoryManager(container)` – Create a manager for any `ContainerArgument` (`EntityArgument` or `Vec3`). - `slotEvent(slot, expectedItem) { … }` – Register handlers for a single slot. - `onTake { … }` – Fires once when the slot transitions from expected item to something else. - `duringTake { … }` – Fires every tick while the slot is not holding the expected item; useful to enforce state. - `onTick { … }` – Runs every tick regardless of state; convenient for housekeeping. - Helpers inside the scope: - `setItemInSlot()` – Put back the expected item into the slot. - `clearAllItemsNotInSlot([targets])` – Clear all other slots. - `killAllItemsNotInSlot()` – Remove dropped items that don’t belong to this slot. - `generateSlotsListeners()` – Emits the `load`/`tick` functions and scoreboard wiring for all registered listeners. - `setBlock(block)` – When the container is a position, place a block (e.g., a chest) before managing its contents. - `clear(slot)`, `clearAll()`, `clearAll(item)` – Utilities to wipe inventory content. Internally, Inventory Manager relies on a scoreboard objective and a tiny helper marker entity (for non-entity containers) to detect state transitions. Names are auto-namespaced and unique per datapack. ## Removing detectors To clean up objectives created by Inventory Manager across runs: ```kotlin dataPack("my_dp") { InventoryManager.removeClickDetectors() } ``` ## Full example This combines a player inventory policy with messaging and a chest that constantly re-seeds its first slot. It mirrors the test coverage used in Kore’s own suite. ```kotlin fun Function.inventoryManagerTests() { val counter = "take_counter" val playerInv = inventoryManager(nearestPlayer()) playerInv.slotEvent(HOTBAR[0], Items.NETHER_STAR) { onTake { title(self(), TitleLocation.ACTIONBAR, text("Don’t take me", Color.RED)) scoreboard.players.add(self(), counter, 1) } duringTake { setItemInSlot() } onTick { clearAllItemsNotInSlot(); killAllItemsNotInSlot() } setItemInSlot() } playerInv.generateSlotsListeners() datapack.load { scoreboard.objectives.add(counter) scoreboard.players.set(playerInv.container as ScoreHolderArgument, counter, 0) } inventoryManager(vec3(0, -59, 0)) { setBlock(Blocks.CHEST) slotEvent(CONTAINER[0], Items.DIAMOND_SWORD) { onTake { tellraw(allPlayers(), text("You took the diamond sword from the chest", Color.RED)) } duringTake { setItemInSlot() } onTick { clearAllItemsNotInSlot(); killAllItemsNotInSlot() } setItemInSlot() } generateSlotsListeners() } } ``` ## See also - [Scheduler](./scheduler) – Run repeated or delayed logic that complements inventory policies. - [Components](../components) – Define complex items (names, lore, enchantments) you can enforce in slots. - [Predicates](../predicates) – Validate component-based item properties in other contexts. - [Scoreboards](../scoreboards) – Background knowledge on objectives used under the hood. --- ## Mannequins --- root: .components.layouts.MarkdownLayout title: Mannequins nav-title: Mannequins description: A guide for creating Mannequins in the world. keywords: minecraft, datapack, kore, guide, mannequins date-created: 2026-01-25 date-modified: 2026-01-25 routeOverride: /docs/helpers/mannequins --- # Mannequins Mannequins are special entities that can display player skins and textures. They are highly customizable, allowing you to change their profile, hidden layers, and main hand. ## Creating a Mannequin You can create a mannequin using the `mannequin` DSL. ```kotlin val myMannequin = mannequin { hiddenLayers(MannequinLayer.CAPE, MannequinLayer.HAT) mainHand = MannequinHand.LEFT playerProfile("Ayfri") } summon(myMannequin.entityType, vec3(), myMannequin.toNbt()) ``` ## Profiles Mannequins can have two types of profiles: `PlayerProfile` and `TextureProfile`. ### Player Profile A player profile uses a player's name or UUID to fetch their skin and properties. ```kotlin mannequin { playerProfile(name = "Steve", id = uuid("8667ba71-b85a-4004-af54-457a9734eed7")) } ``` ### Texture Profile A texture profile allows you to specify a direct texture, and optionally a cape, elytra, and model type. ```kotlin mannequin { textureProfile(texture = "tex") { cape = model("cape") model = MannequinModel.SLIM } } ``` ## Customization Mannequins support additional fields for further customization: ```kotlin mannequin { description = textComponent("Test") hideDescription = false immovable = true pose = MannequinPose.CROUCHING } ``` ### Pose The `pose` field allows you to set the mannequin's pose. Available poses are: - `STANDING` - `CROUCHING` - `SWIMMING` - `FALL_FLYING` - `SLEEPING` ## Hidden Layers You can hide specific layers of the mannequin's skin using the `hiddenLayers` function. Available layers: - `CAPE` - `HAT` - `JACKET` - `LEFT_PANTS_LEG` - `LEFT_SLEEVE` - `RIGHT_PANTS_LEG` - `RIGHT_SLEEVE` ```kotlin mannequin { hiddenLayers(MannequinLayer.JACKET, MannequinLayer.HAT) } ``` ## Main Hand You can set which hand is the main hand of the mannequin. ```kotlin mannequin { mainHand = MannequinHand.RIGHT } ``` --- ## Scheduler --- root: .components.layouts.MarkdownLayout title: Scheduler nav-title: Scheduler description: A guide for scheduling tasks in Kore. keywords: minecraft, datapack, kore, guide, scheduler, schedule, loop, task, tasks date-created: 2025-03-26 date-modified: 2025-03-26 routeOverride: /docs/helpers/scheduler --- # Scheduler in Kore This document explains how to schedule and run tasks at specific times or intervals using Kore's built-in scheduler. Schedulers help automate recurring actions, delayed tasks, and cleanup when tasks are no longer needed. ## Overview A "Scheduler" in Kore lets you: - Schedule a one-time execution of a function or a block of code. - Schedule repeating tasks with a fixed period. - Persist references to scheduled tasks so they can be modified or canceled. All scheduling logic revolves around three core classes: 1. [Scheduler](https://github.com/Ayfri/Kore/blob/master/kore/src/main/kotlin/io/github/ayfri/kore/helpers/Scheduler.kt#L34) – Represents a single scheduled task (with optional delay and period). 2. [UnScheduler](https://github.com/Ayfri/Kore/blob/master/kore/src/main/kotlin/io/github/ayfri/kore/helpers/UnScheduler.kt#L34) – Cancels, or clears, repeating tasks. 3. [SchedulerManager](https://github.com/Ayfri/Kore/blob/master/kore/src/main/kotlin/io/github/ayfri/kore/helpers/SchedulerManager.kt#L42) – Maintains a list of schedulers for a given DataPack and offers convenience methods to add or remove them. **Note:** **Schedulers are saved and loaded from a `scheduler_setup` function that is added to the `minecraft/load.json` tag.** ## Basic Usage Use the DataPack extension function schedulerManager to get or create a SchedulerManager for your datapack: ```kotlin val datapack = dataPack("my_datapack") { // ... schedulerManager { // ... } // ... } ``` Inside the schedulerManager block, you can add schedulers with different behaviors by calling addScheduler. Common calls are: - `addScheduler(delay)` – Executes once after a given delay. - `addScheduler(delay, period)` – Executes once after delay, then repeats every period. - `addScheduler(block)` – Executes right away if no delay or period is specified. In many cases, you'll pass a function block (Function.() -> Command) so you can include DSL commands: ### One-Time Execution If you only want to run a function once after a delay: ```kotlin schedulerManager { addScheduler(5.seconds) { say("I run after 5 seconds!") } } ``` ### Recurrent Execution For periodic tasks: ```kotlin schedulerManager { addScheduler(3.seconds, 1.seconds) { // This code runs first after 3 seconds, then every 1 second. debug("Repeated task!") } } ``` ### Schedule by reference You can also schedule a task by reference: ```kotlin val myFunction = function("my_function") { debug("Hello, world!") } schedulerManager { addScheduler(myFunction, 10.seconds) } ``` ### Canceling a Repeating Task If you have a repeating scheduler, you can unschedule it when you no longer need it: 1. Pass a named function or store the return value of addScheduler. 2. Call unSchedule or removeScheduler. Example removing by reference: ```kotlin val repeatingScheduler = addScheduler(2.seconds, 2.seconds) { debug("Repeat every 2 seconds!") } // Later in the code, for instance in another function: unSchedule(repeatingScheduler.function) // stops the repeating task ``` Or remove by function name: ```kotlin removeScheduler("my_function_to_remove") ``` ### Canceling all tasks You can cancel all tasks by calling clearSchedulers: ```kotlin unScheduleAll() ``` ## Complex Example Below is a more advanced scenario showing how to: 1. Run a periodic task (initial delay + repeating period). 2. Store custom data in a named storage using the /data command. 3. Use execute to conditionally run commands based on stored data. In this example, we keep a running "counter" in a storage and increment it every time the repeating task runs. We also demonstrate how to read from that storage in subsequent commands. ### Full Example ```kotlin import io.github.ayfri.kore.DataPack import io.github.ayfri.kore.arguments.numbers.seconds import io.github.ayfri.kore.arguments.types.resources.StorageArgument import io.github.ayfri.kore.commands.data import io.github.ayfri.kore.commands.execute import io.github.ayfri.kore.commands.value import io.github.ayfri.kore.functions.function import io.github.ayfri.kore.generated.EntityTypes fun DataPack.complexSchedulerExample() { // Create a storage reference for storing and reading data val myStorage = storage("kore_example:counter_storage") // A function that resets the counter at any time function("reset_counter") { data(myStorage) { merge { value("counter", 0) } } say("Counter has been reset to 0!") } schedulerManager { // Turn on debug logs for demonstration debug = true // Create a repeating scheduler. It starts after 2 seconds, repeats every 4 seconds. addScheduler(2.seconds, 4.seconds) { val tempEntity = entity("#temp_entity") // 1) Store the value in a score execute { storeResult { score(tempEntity, "counter") } run { data(myStorage) { get("counter") } } } // 2) Increment the score scoreboard.objective(tempEntity, "counter").add(1) // 3) Store the score in the storage execute { storeResult { storage(myStorage, "counter") } run { scoreboard.objective(tempEntity, "counter").get() } } // 4) Print out the current counter using execute + data get execute { // We can conditionally run commands if the counter is above a threshold, etc. run { // Show the updated counter in chat every time this repeats data(myStorage) { get("counter") } // This prints the raw integer. Let's also do a friendly message: say("Counter incremented!") } } // 5) Condition example: if the counter >= 5, summon something or do logic // Check if the score is >= 5, as we already stored the value in a score execute { // Compare the counter with a threshold, e.g. 5 ifCondition { score(tempEntity, "counter") greaterOrEqual 5 } run { summon(EntityTypes.LIGHTNING_BOLT) say("Counter is >= 5. Summoned lightning!") } } } // Another single-run task in 10 seconds to reset everything addScheduler(10.seconds) { function("reset_counter") say("All done, resetting!") } } } ``` Explanation: 1. We create a custom storage named "kore_example:counter_storage" to maintain a key called "counter". 2. We set up a repeating task (delayed by 2 seconds, repeats every 4 seconds). Inside that repeating schedule: - We store the counter in a score - We increment the counter in storage. - We show the updated counter using data get and say commands. - We run a condition (ifData … >= 5) to check if "counter" has reached 5 or more, then summon a lightning bolt. 3. We also add a single-run scheduler at 10 seconds that calls a function to reset the counter and prints a final message. ## Conclusion - Schedulers let you automate tasks in your datapack with fixed delays or repetition. - Use a SchedulerManager on your DataPack via `schedulerManager { … }`. - Add, remove, or clear schedulers by referencing either the assigned function or the function name. - Combine schedulers with any usual commands for fully automated or repeated logic (debugging, storing data, advanced "execute" conditions, etc.). This powerful system helps keep your datapack logic neatly organized and easy to maintain when you need repeated or delayed operations. --- # Advanced ## Bindings --- root: .components.layouts.MarkdownLayout title: Bindings nav-title: Bindings description: Import existing datapacks and generate Kotlin bindings. keywords: kore, bindings, import, datapack, github, modrinth, curseforge date-created: 2026-01-23 date-modified: 2026-02-03 routeOverride: /docs/advanced/bindings position: 3 --- # Bindings (Import Existing Datapacks) > [!WARNING] > The bindings module is **experimental**. APIs and generated output may change without notice. The bindings module lets you import existing datapacks and generates Kotlin types so you can reference functions, resources, and tags safely in your code. ## Add the module If you are working in a multi-module setup: ```kotlin dependencies { implementation("io.github.ayfri.kore:bindings:") } ``` ## Quick start ```kotlin import io.github.ayfri.kore.bindings.api.importDatapacks importDatapacks { configuration { outputPath("src/main/kotlin") packagePrefix = "kore.dependencies" } github("pixigeko.minecraft-default-data:1.21.8") { subPath = "data" } modrinth("vanilla-refresh") curseforge("repurposed-structures-illager-invasion-compat") url("https://example.com/pack.zip") } ``` ## Using generated bindings When you import a datapack, Kore generates a `data object` with a name derived from the datapack's name (e.g., `VanillaRefresh`). ### Accessing resources Resources are organized by namespace and type. If a datapack has only one namespace, resources are accessible directly: ```kotlin import kore.dependencies.vanillarefresh.VanillaRefresh function("my_function") { // Call a function from the imported datapack function(VanillaRefresh.Functions.MAIN_TICK) // Reference a loot table (see Commands for loot usage) loot(VanillaRefresh.LootTables.BLOCKS.IRON_ORE) } ``` For more on using commands with imported resources, see [Commands](../commands/commands). If the datapack uses multiple namespaces, they are nested: ```kotlin VanillaRefresh.Minecraft.LootTables.CHESTS.ABANDONED_MINESHAFT ``` ### Tags Tags are also imported and can be used wherever a tag of that type is expected: ```kotlin function("my_function") { // Check if the item is in an imported item tag execute { `if`(entity(self), items(VanillaRefresh.Tags.Items.MY_CUSTOM_TAG)) } } ``` ### Pack metadata The generated object also contains information about the original datapack: ```kotlin val path = VanillaRefresh.PATH // Path to the source file/folder val packMeta = VanillaRefresh.pack // PackSection object from pack.mcmeta ``` ## Generated structure For each imported datapack, a Kotlin file is generated containing: - A `data object` named after the datapack. - Nested `data object`s for each namespace (if multiple). - Nested `enum`s or `object`s for each resource type: - `Functions`: All `.mcfunction` files. - `Advancements`: All advancements. - `LootTables`: All loot tables. - `Recipes`: All recipes. - `Tags`: All tags, further nested by type (`Blocks`, `Items`, `Functions`, etc.). - `Worldgen`: All worldgen resources, further nested by type (`Biomes`, `Structures`, etc.). Subfolders in the datapack are preserved as nested objects. ## Explore without generating You can explore the content of a datapack programmatically without generating any code. ```kotlin import io.github.ayfri.kore.bindings.api.exploreDatapacks val datapacks = exploreDatapacks { github("user.repo:main") } val pack = datapacks.first() println("Datapack: ${pack.name}") println("Functions: ${pack.functions.size}") pack.functions.forEach { println(" - ${it.id}") } ``` ## Download sources ### GitHub Downloads a repository or a specific asset from a release. Patterns: - `user.repo`: Latest commit on the default branch. - `user.repo:tag`: Specific tag, branch, or commit. - `user.repo:tag:asset.zip`: Specific asset from a release. ```kotlin github("pixigeko.minecraft-default-data:1.21.8") ``` ### Modrinth Downloads the latest or a specific version of a Modrinth project. Patterns: - `slug`: Latest stable version. - `slug:version`: Specific version ID or number. ```kotlin modrinth("vanilla-refresh") ``` ### CurseForge Downloads from CurseForge. Requires the `CURSEFORGE_API_KEY` environment variable. Patterns: - `projectId`: Latest file for the project. - `projectId:fileId`: Specific file. - `slug`: Project slug. - `slug:fileId`: Specific file for a project slug. - `URL`: Full CurseForge project URL. ```kotlin curseforge("418120") // Project ID ``` ### URL / local path Patterns: - `https://example.com/pack.zip` - `./path/to/pack` (Local folder) - `./path/to/pack.zip` (Local zip) ## Configuration ### Global configuration Defined in the `configuration {}` block: | Property | Default | Description | |----------------------|---------------------------------|--------------------------------------------------| | `outputPath` | `build/generated/kore/imported` | Directory where Kotlin files will be generated. | | `packagePrefix` | `kore.dependencies` | Base package for all generated bindings. | | `generateSingleFile` | `true` | If true, generates one Kotlin file per datapack. | | `skipCache` | `false` | If true, re-downloads even if already in cache. | | `debug` | `false` | Prints extra information during the process. | ### Per-datapack configuration Defined in the block following a source: ```kotlin github("user.repo") { remappedName = "MyPack" // Change the generated object name packageName = "custom.pkg" // Change the package for this pack subPath = "datapacks/main" // Only import from this subfolder includes = listOf("data/**") // Only include files matching these patterns excludes = listOf("**/test/**") // Exclude files matching these patterns } ``` ## Cache Downloaded files are cached in `~/.kore/cache/datapacks` to speed up subsequent runs. Use `skipCache = true` in the global configuration or delete the cache folder to force a re-download. ## Troubleshooting - **Rate Limits**: GitHub API is limited for unauthenticated calls. - **CurseForge API**: Ensure your API key is valid and has permissions for the project. - **Invalid resources**: If a resource type is unknown to Kore, it will be skipped to avoid generating invalid code. --- ## GitHub Actions Publishing --- root: .components.layouts.MarkdownLayout title: GitHub Actions Publishing nav-title: GitHub Actions Publishing description: Automatically publish your Kore datapacks using GitHub Actions with mc-publish. keywords: minecraft, datapack, kore, github actions, publishing, automation, ci/cd date-created: 2025-09-30 date-modified: 2025-09-30 routeOverride: /docs/advanced/github-actions-publishing --- # GitHub Actions Publishing This guide shows you how to automatically publish your Kore-generated datapacks to various platforms using GitHub Actions and the `mc-publish` action. ## Prerequisites - A GitHub repository containing your Kore project - Accounts on target platforms (Modrinth, CurseForge, etc.) - API tokens for each platform you want to publish to ## What is mc-publish? [mc-publish](https://github.com/Kira-NT/mc-publish) is a GitHub Action that simplifies publishing Minecraft projects across multiple platforms including Modrinth, CurseForge, and GitHub Releases. It automatically detects project metadata and handles the complex publication process with minimal configuration. ## Setting Up GitHub Secrets Before configuring your workflow, you'll need to add your platform tokens as GitHub secrets: 1. Go to your repository's **Settings** → **Secrets and variables** → **Actions** 2. Add the following secrets: - `MODRINTH_TOKEN`: Your Modrinth API token - `CURSEFORGE_TOKEN`: Your CurseForge API token - `GITHUB_TOKEN` is automatically provided by GitHub > **Note:** Only add secrets for platforms you plan to publish to. ## Basic Workflow Setup Create `.github/workflows/publish.yml` in your repository: ```yaml name: Publish Datapack on: release: types: [ published ] workflow_dispatch: # Allow manual triggering jobs: publish: runs-on: ubuntu-latest permissions: contents: write steps: - name: Checkout repository uses: actions/checkout@v5 - name: Set up JDK 21 uses: actions/setup-java@v5 with: cache: gradle distribution: 'temurin' java-version: 21 - name: Ensure Gradle is executable run: chmod +x gradlew - name: Setup Gradle uses: gradle/actions/setup-gradle@v4 - name: Build datapack run: ./gradlew build - name: Publish to platforms uses: Kir-Antipov/mc-publish@v3.3 with: # Modrinth configuration modrinth-id: YOUR_PROJECT_ID modrinth-token: ${{ secrets.MODRINTH_TOKEN }} # CurseForge configuration curseforge-id: YOUR_PROJECT_ID curseforge-token: ${{ secrets.CURSEFORGE_TOKEN }} # GitHub Releases github-token: ${{ secrets.GITHUB_TOKEN }} ``` Ensure to use `datapack.generateZip()` in your build script to generate a zip file containing your datapack. ## Advanced Configuration For more control over the publishing process, you can customize various aspects: ```yaml - name: Publish to platforms uses: Kir-Antipov/mc-publish@v3.3 with: # Project identification modrinth-id: AANobbMI modrinth-token: ${{ secrets.MODRINTH_TOKEN }} curseforge-id: 394468 curseforge-token: ${{ secrets.CURSEFORGE_TOKEN }} github-token: ${{ secrets.GITHUB_TOKEN }} # Version configuration name: "My Datapack v${{ github.ref_name }}" version: ${{ github.ref_name }} version-type: release # alpha, beta, or release # File selection files: | out/*.zip !out/*-unfinished.zip # Supported game versions game-versions: | 1.21 1.21.5 1.21.6 # Mod loaders (if exporting to Jars) loaders: | fabric forge # Release configuration changelog-file: CHANGELOG.md dependencies: | fabric-api(required){modrinth:P7dR8mSH}{curseforge:306612} # Platform-specific settings modrinth-featured: true curseforge-java-versions: | Java 21 github-prerelease: ${{ contains(github.ref_name, 'beta') || contains(github.ref_name, 'alpha') }} github-draft: false ``` ## Kore-Specific Configuration ## Workflow Triggers You can configure when the publishing workflow runs: ```yaml on: # Trigger on new releases release: types: [ published ] # Trigger on version tags push: tags: - 'v*' # Allow manual triggering workflow_dispatch: inputs: version-type: description: 'Release type' required: true default: 'release' type: choice options: - release - beta - alpha ``` ## Platform-Specific Features ### Modrinth - Supports featured projects - Automatic dependency resolution - Rich markdown changelog support ```yaml modrinth-featured: true modrinth-unfeature-mode: subset ``` ### CurseForge - Java version specification - Custom display name support ```yaml curseforge-java-versions: | Java 17 Java 21 curseforge-display-name: "My Awesome Datapack" ``` ### GitHub Releases - Draft and prerelease support - Asset management ```yaml github-draft: false github-prerelease: ${{ contains(github.ref_name, 'pre') }} github-tag: ${{ github.ref_name }} ``` This helps mc-publish automatically detect project metadata. ## Best Practices ### 1. Version Management Use semantic versioning and Git tags: ```bash git tag v1.0.0 git push origin v1.0.0 ``` ### 2. Changelog Management Maintain a `CHANGELOG.md` file following [Keep a Changelog](https://keepachangelog.com/) format: ```markdown # Changelog ## [1.0.0] - 2025-09-30 ### Added - Initial release with basic functionality - Support for Minecraft 1.21 ### Changed - Improved performance of item generation ### Fixed - Fixed issue with advancement rewards ``` ### 3. Testing Before Publishing Add a test job before publishing: ```yaml jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v5 - name: Set up JDK 21 uses: actions/setup-java@v5 with: java-version: '21' distribution: 'temurin' - name: Run tests run: ./gradlew test publish: needs: test runs-on: ubuntu-latest # ... publishing steps ``` ## Troubleshooting ### Common Issues 1. **Missing files**: Ensure you exported the datapack to the correct directory 2. **Invalid tokens**: Verify your secrets are correctly set in GitHub 3. **Permission errors**: Ensure the workflow has `contents: write` permission ### Debugging Enable debug logging by adding: ```yaml env: ACTIONS_RUNNER_DEBUG: true ACTIONS_STEP_DEBUG: true ``` ## Complete Example Here's a complete workflow for a Kore datapack project: ```yaml name: Publish Datapack on: release: types: [ published ] workflow_dispatch: jobs: publish: runs-on: ubuntu-latest permissions: contents: write steps: - name: Checkout repository uses: actions/checkout@v5 - name: Set up JDK 21 uses: actions/setup-java@v5 with: cache: gradle distribution: 'temurin' java-version: 21 - name: Ensure Gradle is executable run: chmod +x gradlew - name: Setup Gradle uses: gradle/actions/setup-gradle@v4 - name: Generate datapack run: ./gradlew run - name: Publish to platforms uses: Kir-Antipov/mc-publish@v3.3 with: name: "${{ github.event.repository.name }} ${{ github.ref_name }}" version: ${{ github.ref_name }} version-type: release files: ${{ github.event.repository.name }}-${{ github.ref_name }}.zip game-versions: | 1.21 1.21.5 1.12.6 modrinth-id: YOUR_MODRINTH_ID modrinth-token: ${{ secrets.MODRINTH_TOKEN }} modrinth-featured: true curseforge-id: YOUR_CURSEFORGE_ID curseforge-token: ${{ secrets.CURSEFORGE_TOKEN }} github-token: ${{ secrets.GITHUB_TOKEN }} github-tag: ${{ github.ref_name }} changelog-file: CHANGELOG.md ``` ## See Also - [Creating a Datapack](./creating-a-datapack) - [Configuration](./configuration) - [mc-publish Documentation](https://github.com/Kir-Antipov/mc-publish) - [GitHub Actions Documentation](https://docs.github.com/en/actions) --- ## Known Issues --- root: .components.layouts.MarkdownLayout title: Known Issues nav-title: Known Issues description: A list of known issues and limitations in Kore. keywords: kore, guide, documentation, known issues date-created: 2025-08-27 date-modified: 2025-08-27 routeOverride: /docs/advanced/known-issues --- # Missing features ## SNBT Some SNBT features are not supported yet. Kore depends on another library for writing SNBT which does not support them yet.
The main features that are not supported are: - Heterogeneous lists (e.g. `[1, "string", {key: "value"}]`) - SNBT operations (`bool(arg)`, `uuid(arg)`) Such features would be very hard to implement just in Kore, but if you really need them, maybe we could consider creating our own SNBT library. ## Resource Packs Kore is only designed to create Data Packs, not Resource Packs, but it could be implemented in the future. ## Updates Kore is sometimes a little bit outdated, and some features may not work as expected. I am working on my free time to keep it up to date, so fill free to help me update it by contributing to the project. --- ## Test Features --- root: .components.layouts.MarkdownLayout title: Test Features nav-title: Test Features description: A comprehensive guide for creating test instances and test environments in Minecraft's GameTest framework with Kore. keywords: minecraft, datapack, kore, guide, test, testing, environment, instance, gametest, automation date-created: 2025-01-08 date-modified: 2025-01-08 routeOverride: /docs/advanced/test-features --- # Test Features Minecraft 1.21.5 (Snapshot 25w03a) introduced a major overhaul to the **GameTest framework ** - an automated end-to-end testing system for datapack functionality. Kore provides comprehensive support using a type-safe Kotlin DSL that generates JSON files for the `test_instance` and `test_environment` registries. ## Test Environments Test environments define preconditions and context for automated test execution. ### Creating Test Environments ```kotlin dataPack("my_datapack") { testEnvironments { // Environment definitions } } ``` ### Environment Types #### Combined Environments Combine multiple conditions using `allOf`: ```kotlin testEnvironments { val rules = gameRules("no_mobs") { this[Gamerules.DO_MOB_SPAWNING] = false } val time = timeOfDay("dawn", 1000) val weather = weather("rain", Weather.RAIN) val combined = allOf("complex_test", rules, time, weather) } ``` #### Function Environment Execute setup and teardown functions: ```kotlin val myFunction = function("test_function") { say("Hello, world!") } testEnvironments { function("setup_env") { setup(myFunction) teardown(myFunction) } } ``` #### Game Rules Environment Create controlled testing conditions: ```kotlin testEnvironments { gameRules("controlled_env") { this[Gamerules.DO_DAYLIGHT_CYCLE] = false this[Gamerules.DO_FIRE_TICK] = false this[Gamerules.DO_MOB_SPAWNING] = false this[Gamerules.MAX_ENTITY_CRAMMING] = 100 this[Gamerules.RANDOM_TICK_SPEED] = 0 } } ``` #### Time Environment Ensure consistent timing: ```kotlin testEnvironments { val morningEnv = timeOfDay("morning", 1000) // Dawn val noonEnv = timeOfDay("noon", 6000) // Noon val nightEnv = timeOfDay("night", 18000) // Midnight } ``` #### Weather Environment Control weather conditions: ```kotlin testEnvironments { val clearEnv = weather("clear_weather", Weather.CLEAR) val rainEnv = weather("rain_weather", Weather.RAIN) val stormEnv = weather("storm_weather", Weather.THUNDER) } ``` ## Test Instances Test instances define automated tests with structures and execution parameters. ### Test Types - **Block-Based**: Use test blocks (Start, Log, Fail, Accept) with redstone logic - **Function-Based**: Use programmatic function control ### Basic Examples ```kotlin testInstances { // Block-based test testInstance("basic_test") { blockBased() environment(env) maxTicks = 100 structure(Structures.AncientCity.Structures.BARRACKS) } // Function-based test testInstance("function_test") { environment(env) functionBased() maxTicks = 200 structure(Structures.AncientCity.Structures.BARRACKS) function { setup(myFunction) teardown(myFunction) } } } ``` ### Advanced Configuration ```kotlin testInstance("advanced_test") { clockwise90() // Structure rotation environment(env) functionBased() manualOnly = true // Manual execution only maxAttempts = 3 // Retry attempts maxTicks = 300 // Timeout required = true // Must pass requiredSuccesses = 2 // Success count needed setupTicks = 20 // Preparation time skyAccess = false // Structure placement structure(Structures.AncientCity.Structures.BARRACKS) function { setup(myFunction) teardown(myFunction) } } ``` ## Using Predefined Structures ```kotlin // Ancient City structure(Structures.AncientCity.CityCenter.CITY_CENTER_1) structure(Structures.AncientCity.Structures.BARRACKS) // Bastion structure(Structures.Bastion.Treasure.Bases.LAVA_BASIN) structure(Structures.Bastion.Units.CenterPieces.CENTER_0) // Simple structures structure(Structures.Igloo.TOP) structure(Structures.Shipwreck.RIGHTSIDEUP_FULL) // Trial Chambers structure(Structures.TrialChambers.Chamber.ASSEMBLY) structure(Structures.TrialChambers.Corridor.ENTRANCE_1) // Villages structure(Structures.Village.Desert.Houses.DESERT_TEMPLE_1) structure(Structures.Village.Plains.Houses.PLAINS_SMALL_HOUSE_1) ``` ## Test Commands ### Test Selectors ```kotlin // Basic selectors allTests() // "*:*" - all tests minecraftTests() // "minecraft:*" - minecraft tests testSelector("my_pack:*") // All tests in namespace testSelector("*_combat") // Tests ending with "_combat" testSelector("test_?") // Single character wildcard ``` ### Command Examples ```kotlin function("test_example") { test { val selector = testSelector("my_pack:test_*") // Basic usage run(selector) runClosest() runMultiple(selector, 5) // Management create(TestInstanceArgument("test", "pack")) locate(selector) pos("variable") // Cleanup clearAll() resetClosest() stop() // Verification verify(TestInstanceArgument("test1", "pack"), TestInstanceArgument("test2", "pack")) } } ``` ## Test Execution ### Manual Commands ```mcfunction # Basic execution /test run my_datapack:basic_test /test runmultiple my_datapack:basic_test my_datapack:function_test /test runclosest /test runfailed # Management /test create my_datapack:new_test 16 16 16 /test locate my_datapack:test_* /test pos test_position # Cleanup /test clearall 15 /test resetclosest /test stop ``` ## Complete Example ```kotlin fun DataPack.createTestSuite() { // Test functions val cleanupFunction = function("test_cleanup") { say("Cleaning up test") } val setupFunction = function("test_setup") { say("Setting up test") } // Environments testEnvironments { val controlled = gameRules("controlled") { this[Gamerules.DO_DAYLIGHT_CYCLE] = false this[Gamerules.DO_MOB_SPAWNING] = false this[Gamerules.RANDOM_TICK_SPEED] = 0 } val dayTime = timeOfDay("day", 6000) val controlledDay = allOf("controlled_day", controlled, dayTime) } testInstances { // Basic redstone test testInstance("redstone_basic") { blockBased() environment(testEnvironmentsBuilder.allOf("controlled_day", testEnvironmentsBuilder.gameRules("controlled") { this[Gamerules.DO_DAYLIGHT_CYCLE] = false }, testEnvironmentsBuilder.timeOfDay("day", 6000) )) maxTicks = 100 required = true structure(Structures.AncientCity.Structures.BARRACKS) } // Complex function test testInstance("complex_logic_test") { environment(testEnvironmentsBuilder.gameRules("controlled") { this[Gamerules.DO_DAYLIGHT_CYCLE] = false this[Gamerules.DO_MOB_SPAWNING] = false this[Gamerules.RANDOM_TICK_SPEED] = 0 }) functionBased() maxAttempts = 2 maxTicks = 200 required = true structure(Structures.AncientCity.Structures.BARRACKS) function { setup(setupFunction) teardown(cleanupFunction) } } // Directional test testInstance("directional_blocks") { blockBased() clockwise90() environment(testEnvironmentsBuilder.gameRules("controlled") { this[Gamerules.DO_DAYLIGHT_CYCLE] = false }) maxTicks = 120 required = true structure(Structures.AncientCity.Structures.BARRACKS) } // Lightning test testInstance("lightning_rod_test") { blockBased() environment(testEnvironmentsBuilder.weather("thunder", Weather.THUNDER)) maxAttempts = 3 maxTicks = 400 skyAccess = true structure(Structures.AncientCity.Structures.BARRACKS) } // Mob spawning test testInstance("mob_spawning") { blockBased() environment(testEnvironmentsBuilder.timeOfDay("night", 18000)) maxTicks = 300 setupTicks = 40 structure(Structures.AncientCity.Structures.BARRACKS) } } } ``` ## Best Practices - **Combine environments** with `allOf` for complex scenarios - **Mark critical tests** as `required = true` - **Set appropriate timeouts** with `maxTicks` - **Use controlled conditions** with game rules for predictable results - **Use predefined structures** from `Structures` constants ## API Reference ### Test Environment Functions ```kotlin testEnvironments { allOf(name, ...environments) function(name) { setup(...); teardown(...) } gameRules(name) { this[rule] = value } timeOfDay(name, time) weather(name, weather) } ``` ### Test Instance Functions ```kotlin testInstances { testInstance(name) { blockBased() / functionBased() environment(env) function { setup(...); teardown(...) } maxTicks = 100 required = true structure(Structures.Category.STRUCTURE_NAME) // rotation, timing, and other properties } } ``` ### Game Rules Configuration ```kotlin gameRules("name") { this[Gamerules.DO_DAYLIGHT_CYCLE] = false this[Gamerules.DO_FIRE_TICK] = false this[Gamerules.DO_MOB_SPAWNING] = false this[Gamerules.MAX_ENTITY_CRAMMING] = 100 this[Gamerules.RANDOM_TICK_SPEED] = 0 } ``` This DSL provides a type-safe way to create automated tests for Minecraft datapacks using the GameTest framework introduced in snapshot 25w03a. --- # Home ## Home --- root: .components.layouts.MarkdownLayout title: Home nav-title: Home description: Welcome to the Kore wiki! keywords: minecraft, datapack, kore, guide date-created: 2024-04-06 date-modified: 2026-02-03 routeOverride: /docs/home position: 0 --- # Kore **Welcome to the Kore wiki!** Kore is a Kotlin library for building Minecraft datapacks with a concise, type-safe Kotlin DSL. It focuses on readable builders, stable generation of datapack JSON, and tight integration with vanilla concepts (functions, loot tables, predicates, worldgen, ...). ## Quick start - **Getting started**: Check out the [Getting Started](/docs/getting-started) guide for a step-by-step introduction to creating your first datapack. - **Prerequisites**: Java 21+ and a Kotlin-capable build environment. - **Starter template**: use the `Kore Template` for a ready-to-run project: [`Kore Template`](https://github.com/Ayfri/Kore-Template). - **Create & generate**: see [Creating A Datapack](./creating-a-datapack) for lifecycle and output options (`.generate()`, `.generateZip()`, `.generateJar()`). {{{ .components.doc.FeatureGrid }}} ### Minimal example ```kotlin fun main() { dataPack("example") { function("display_text") { tellraw(allPlayers(), textComponent("Hello World!")) } }.generateZip() } ``` ## Essential reading - **[Getting Started](./getting-started)**: step-by-step guide to create your first datapack. - **[Creating A Datapack](./guides/creating-a-datapack)**: lifecycle, output paths, and generation options. - **[Commands](./commands/commands)**: comprehensive guide to all Minecraft commands with examples. - **[Functions](./commands/functions)**: building functions, tags, and command helpers. ## Full documentation index ### Core Guides - [Configuration](./guides/configuration) - JSON formatting and generation options. ### Commands - [Macros](./commands/macros) - dynamic command arguments for reusable functions. ### Concepts - [Components](./concepts/components) - item/component builders and custom components. - [Chat Components](./concepts/chat-components) - formatted messages and text components. - [Colors](./concepts/colors) - chat colors and formatting options. - [Scoreboards](./concepts/scoreboards) - objectives, teams, and scoreboard displays. ### Data-Driven - [Predicates](./data-driven/predicates) - reusable conditions used by loot tables, advancements and item modifiers. - [Loot Tables](./data-driven/loot-tables) & [Item Modifiers](./data-driven/item-modifiers) - tables, pools and `/item modify` helpers. - [Recipes](./data-driven/recipes) & [Advancements](./data-driven/advancements) - crafting, rewards and integration. - [Enchantments](./data-driven/enchantments) - custom enchantment definitions. - [Dialogs](./data-driven/dialogs) - NPC dialog systems. - [Worldgen](./data-driven/worldgen) - biomes, features and dimension examples. - [Tags](./data-driven/tags) - custom tag definitions for grouping items, blocks, entities, etc. ### Helpers - [Display Entities](./helpers/display-entities) - text, block, and item displays. - [Inventory Manager](./helpers/inventory-manager) - inventory manipulation helpers. - [Mannequins](./helpers/mannequins) - armor stand helpers. - [Scheduler](./helpers/scheduler) - delayed function execution patterns. ### Advanced - [Bindings](./advanced/bindings) - import existing datapacks and generate Kotlin bindings (experimental). - [GitHub Actions Publishing](./advanced/github-actions-publishing) - automate datapack publishing. - [Test Features (GameTest)](./advanced/test-features) - testing datapacks with GameTest. - [Known Issues](./advanced/known-issues) - workarounds and limitations. ## Short tips - Keep builders small and reusable; prefer extracting predicates and modifiers. - Enable `prettyPrint` in [`Configuration`](./guides/configuration) during development for readable JSON. - Use [`Components`](./concepts/components) + [ `Predicates`](./data-driven/predicates) together for robust item checks and inventory management. ## Known issues Check out the [Known Issues](/docs/advanced/known-issues) page for a list of known issues and workarounds. ## Community & source - **Repository**: [Kore](https://github.com/Ayfri/Kore) - **Starter template**: [Kore Template](https://github.com/Ayfri/Kore-Template) - **LLM-friendly documentation**: [llms.txt](https://kore.ayfri.com/llms.txt) | [llms-full.txt](https://kore.ayfri.com/llms-full.txt) For hands-on examples, follow the doc pages above - most pages include runnable snippets and links to test cases in the repository. --- # Getting started ## Getting Started --- root: .components.layouts.MarkdownLayout title: Getting Started nav-title: Getting Started description: Step-by-step guide to create your first Minecraft datapack with Kore. keywords: minecraft, datapack, kore, getting started, quickstart, kotlin date-created: 2025-08-21 date-modified: 2026-02-03 routeOverride: /docs/getting-started position: 1 --- # Getting Started This guide takes you from zero to a working datapack using Kore and Kotlin. It also highlights a few Kotlin/Kore tips that Java beginners often miss. ## Prerequisites - [Java 21 (JDK 21)](https://jdk.java.net/archive/) or higher - Kotlin + Gradle (using the Gradle wrapper is recommended) - An IDE with Kotlin support (IntelliJ IDEA recommended) - Basic knowledge of Minecraft datapacks will help you. ## Option A: Use the Kore Template (recommended) The fastest way to start is the Kore Template repository. It's preconfigured and ready to run. - On GitHub: open https://github.com/Ayfri/Kore-Template and click “Use this template” to create your repo, or clone it directly. - In IntelliJ IDEA: 1) File > New > Project from Version Control 2) Enter URL: https://github.com/Ayfri/Kore-Template and choose a directory 3) Open the project, trust it, let Gradle import/sync 4) In the `src/main/kotlin` folder, open `Main.kt` and run the `main` function The template already sets Java 21 and enables the required Kotlin options. ## Option B: Add Kore to an existing project Add the dependency to your build file. ### Gradle (Kotlin) ```kotlin dependencies { implementation("io.github.ayfri.kore:kore:VERSION") } ``` ### Gradle (Groovy) ```groovy dependencies { implementation 'io.github.ayfri.kore:kore:VERSION' } ``` ### Maven ```xml io.github.ayfri.kore kore VERSION ``` ### Amper ```yaml dependencies: - io.github.ayfri.kore:kore:VERSION ``` ### Kotlin configuration Enable context receivers (parameters) and set Java toolchain in your `build.gradle.kts`: ```kotlin kotlin { compilerOptions { freeCompilerArgs.add("-Xcontext-parameters") } jvmToolchain(21) } ``` ## Your first datapack (Hello, Kore) Create a `Main.kt` and paste: ```kotlin fun main() { val datapack = dataPack("hello_kore") { function("display_text") { tellraw(allPlayers(), textComponent("Hello Kore!")) } pack { description = textComponent("Hello Kore datapack") } } // Generate a zip you can drop in your world's datapacks folder datapack.generateZip() // Alternatively, generate files in a folder: datapack.generate() } ``` - Run `main` from your IDE. - A datapack archive is produced; put it into your Minecraft world's `datapacks/` folder. - In-game, run: `/function hello_kore:display_text`. ## Tips for Kotlin newcomers - **Null safety:** Kotlin's type system distinguishes nullable and non-nullable types. Use `?` for nullable types and prefer safe calls ( `?.`) and the Elvis operator (`?:`). See [Null Safety](https://kotlinlang.org/docs/null-safety.html). ```kotlin val name: String? = System.getenv("USER") val length: Int = name?.length ?: 0 // safe call + default when null ``` - **Type inference:** You rarely need to specify types explicitly-Kotlin infers them for you. Use `val` for read-only variables and `var` for mutable ones. Prefer `val` for immutability. ```kotlin val count = 0 // Int inferred var title = "Hello" // String inferred // Prefer val; use var only when you need to reassign ``` - **Smart casts:** The compiler automatically casts types after checks (e.g., `if (x is String) { x.length }`). ```kotlin fun lengthIfString(x: Any): Int = if (x is String) x.length else 0 ``` - **Extension functions:** Add new functions to existing types without inheritance. Kore uses this for DSLs. See [Extensions](https://kotlinlang.org/docs/extensions.html). ```kotlin fun String.titleCase(): String = replaceFirstChar { it.titlecase() } // Usage: "kore".titleCase() -> "Kore" ``` - **Standard library: ** Kotlin's standard library is rich-explore [kotlinlang.org/api/latest/jvm/stdlib/](https://kotlinlang.org/api/latest/jvm/stdlib/). ```kotlin val names = listOf("Alex", "Steve", "Sam") val shout = names.map { it.uppercase() }.filter { it.startsWith("S") } ``` - DSLs + context receivers: Inside `dataPack { ... }`, many builders are available without qualifiers. The compiler flag `-Xcontext-parameters` is required. - Extract helpers with extensions: Attach utilities to `DataPack` to keep code organized: ```kotlin fun DataPack.myBasics() = function("setup") { // your setup } fun main() = dataPack("my_pack") { myBasics() } ``` - Name collisions in builders: Some builder names exist in multiple contexts (e.g., `nbt`, `predicate`). If your IDE auto-imports the wrong symbol, qualify with `this.` inside the DSL scope to target the correct function, or fix the import. Example: ```kotlin predicate("my_function") { this.nbt("my_nbt") { /* ... */ } // Use this to correctly import nbt() } ``` Then just remove `this.` now that you know the import is correct. - Idempotency: Declaring the same record twice is safe, Kore only keeps the last one. - **Kotlin Playground:** Try out code online at [play.kotlinlang.org](https://play.kotlinlang.org/). - **Official docs:** The [Kotlin documentation](https://kotlinlang.org/docs/home.html) is excellent for learning language features and best practices. ## Project layout and outputs - Your code lives under `src/main/kotlin` (template already set). - Generated datapacks: `.generate()` writes a folder; `.generateZip()` writes a zip; `.generateJar()` targets mod loaders. - During development, enable pretty JSON in [Configuration](./configuration) to inspect outputs. - Split your code into multiple files to keep things organized. ## Troubleshooting - Unresolved DSL symbols: Ensure the Kore dependency is on the classpath and `-Xcontext-parameters` is enabled. - Java version errors: Verify `jvmToolchain(21)` and that your JDK is 21. - Dev loop: Re-run your program after edits to regenerate the datapack. ## What to read next Essential pages for new users: - [Creating a Datapack](./guides/creating-a-datapack) - lifecycle and output options - [Commands](./commands/commands) - comprehensive guide to all Minecraft commands - [Functions](./commands/functions) - building functions and command helpers - [Recipes](./data-driven/recipes) - how to create recipes - [Bindings](./advanced/bindings) - import existing datapacks (experimental) For the full documentation index, see [Home](./home). ## See also - “Hello World” walkthrough: [Kore Hello World](https://ayfri.com/articles/kore-hello-world/) - Minecraft wiki: [Datapack](https://minecraft.wiki/w/Data_pack) - [Kore on GitHub](https://github.com/Ayfri/Kore) - [Kore on Maven Central](https://central.sonatype.com/search?q=io.github.ayfri.kore) - [Kore on Discord](https://discord.ayfri.com) ---