# Contributing: The Generation Pipeline

> How Kore's generation module downloads Minecraft source data and codegens enums and argument types. Covers registries, data sources, caching, and the generator extension API for contributors.

Updated 2026-10-02. Canonical: https://kore.ayfri.com/docs/contributing/generation-pipeline

`generation/` is a standalone Kotlin/JVM app, not a library other modules depend on. Running it writes Kotlin files
straight into `kore/src/commonMain/kotlin/io/github/ayfri/kore/generated` - it is the *only* thing allowed to touch that
folder. The folder is gitignored: every `kore` compilation regenerates it through the cacheable
`:generation:generateSources` task.

## What it does

`generation/src/main/kotlin/Main.kt` runs, in order:

1. Clear `kore/src/commonMain/kotlin/io/github/ayfri/kore/generated` and (with `--reload-cache`) the download cache.
2. Download datapacks, the default datapack version, gamerules and item component types.
3. Run every simple generator ([`launchAllSimpleGenerators`](https://github.com/ayfri/kore/blob/master/generation/src/main/kotlin/generators/generators.kt)) - lists and registries that become
   enums or enum trees.
4. Run the argument type generator ([`launchArgumentTypeGenerators`](https://github.com/ayfri/kore/blob/master/generation/src/main/kotlin/generators/arguments.kt)) - registries that become typed
   `*Argument` / `*OrTagArgument` / `*TagArgument` interfaces.
5. Write the resolved Minecraft version into the generated package.

Source data is fetched from the [`PixiGeko/Minecraft-generated-data`](https://github.com/PixiGeko/Minecraft-generated-data) GitHub repo, pinned to the
`minecraft.version` in `gradle.properties`. Downloads are cached under `generation/build/cache`; pass
`--reload-cache` to force a re-download after a Minecraft version bump.

## Adding a new generated list or registry

Most new registries only need an entry in [`generators/generators.kt`](https://github.com/ayfri/kore/blob/master/generation/src/main/kotlin/generators/generators.kt), inside `lists` (plain
resource lists, e.g. `loot_table`) or `registries` (vanilla registries, e.g. `item`):

```kotlin
gen("TradeSets", "trade_set")
```

`gen(name, fileName) { ... }` ([`generators/Generator.kt`](https://github.com/ayfri/kore/blob/master/generation/src/main/kotlin/generators/Generator.kt)) takes the enum name and the upstream file
name, and exposes a small builder for the common cases:

- `argumentClassName` - override the generated `*Argument` type name when it should differ from `name` (for example
  `"Model M"` routes the argument to `arguments/types/resources` instead of the generated tree - see the
  `M`-suffix rule in [Contributing: Creating a New Generator](https://kore.ayfri.com/docs/contributing/creating-a-new-generator.md)).
- `transform { ... }` - strip a suffix/prefix from raw entries (`.json`, `.ogg`, `minecraft:`, ...).
- `enumTree` / `separator` - force or configure a path-based enum tree instead of a flat enum, for entries that
  contain `/`.
- `extractEnums(...)` - split out a sub-enum from entries sharing a prefix.
- `tagsParents(...)` / `subInterfacesParents(...)` - map resource folders or sub-namespaces to their parent
  argument type, used by the `Tags` and `Textures` generators.

Whether an entry lands in `lists` or `registries` only changes which upstream `.txt` folder it reads from
(`custom-generated/lists/...` vs `custom-generated/registries/...`); both feed the same enum/enum-tree codegen.

Registries that need a typed argument (referenced from other DSL builders, taggable, etc.) are handled separately by
`launchArgumentTypeGenerators()` in [`generators/arguments.kt`](https://github.com/ayfri/kore/blob/master/generation/src/main/kotlin/generators/arguments.kt) - it reads the registry list straight
from the datapack report (`minecraft-generated/reports/datapack.json`) rather than from `generators.kt`, so a
vanilla registry usually needs no manual entry at all. `additionalTypes`/`ignoreList` in that file are only for
registries the report doesn't expose or that already have a hand-written model (`block`, `item`, `tag`).

## Running it

```
./gradlew :generation:run
```

Add `--args='--reload-cache'` after bumping the Minecraft version to invalidate the download cache.

Once it finishes, read the new files in `kore/src/commonMain/kotlin/io/github/ayfri/kore/generated` (enums and
`Argument` types alike) to confirm the new registry produced the expected enum/argument shape before writing any DSL
code against it.

## See also

- [Contributing: Architecture and Patterns](https://kore.ayfri.com/docs/contributing/architecture-and-patterns.md)
- [Contributing: Creating a New Generator](https://kore.ayfri.com/docs/contributing/creating-a-new-generator.md)
