Skip to content

About

A DataGenerator library mod for mod makers to create Patchouli Books with no JSON error

Resources

Stars

0 stars

Watchers

0 watching

Forks

 
 

Repository files navigation

Patchouli DataGen

A Kotlin-first data generator for Patchouli books on NeoForge 1.21.1.

Creating a book

Extend PatchouliBookProvider and return a book from buildBook. Categories and entries are registered on the book, so no consumers, explicit save calls, or terminal build calls are needed.

class GuideBookProvider(
	generator: DataGenerator,
	registries: HolderLookup.Provider
) : PatchouliBookProvider(generator, registries, "guide") {

	private lateinit var basics: PatchouliBookCategory

	override fun buildBook() = patchouliBook(
		namespace = "example",
		name = "Example Guide",
		landingText = "Welcome to the guide."
	) {
		creativeTab = "minecraft:tools_and_utilities"
		addCategories()
		addEntries()
	}

	private fun PatchouliBook.addCategories() {
		basics = category(
			"basics",
			"Basics",
			"Everything needed to get started.",
			Items.BOOK
		)
	}

	private fun PatchouliBook.addEntries() {
		entry("welcome", basics, "Welcome", Items.PAPER) {
			textPage("Your first page", "Getting Started")

			craftingPage(Items.CRAFTING_TABLE) {
				text = "Craft one before continuing."
			}
		}
	}
}

Splitting categories and entries into receiver methods keeps large books shallow. The complete example includes subcategories, item stacks, recipes, formatted text, and inline multiblocks.

Category and entry icons accept either an ItemLike or an ItemStack. Stack components are included in the generated Patchouli item string.

Entry definitions are applied after the patchouliBook block has registered every entry. This allows entries to link directly to entries declared later, including circular links:

lateinit var firstEntry: PatchouliBookEntry
lateinit var secondEntry: PatchouliBookEntry

firstEntry = entry("first", basics, "First", Items.PAPER) {
	textPage(internalLink(secondEntry, "Continue"))
}

secondEntry = entry("second", basics, "Second", Items.BOOK) {
	textPage(internalLink(firstEntry, "Go back"))
}

This resolution step is handled by patchouliBook; providers receive a completed book.

Register the provider during GatherDataEvent:

generator.addProvider(
	event.includeClient(),
	GuideBookProvider(generator, event.lookupProvider.get())
)

Modonomicon

Modonomicon support is optional. Patchouli DataGen can be installed and loaded without Modonomicon; projects that use this DSL must add Modonomicon to their own compile and runtime dependencies.

Extend ModonomiconBookProvider and build the book with modonomiconBook:

class GuideBookProvider(
	defaultLanguage: BiConsumer<String, String>
) : ModonomiconBookProvider(
	bookId = "guide",
	namespace = "example",
	name = "Example Guide",
	tooltip = "A useful guide",
	defaultLanguage = defaultLanguage
) {
	override fun buildBook() = modonomiconBook(
		namespace = "example",
		saveName = "guide",
		name = "Example Guide",
		tooltip = "A useful guide",
		registries = registries()
	) {
		displayMode = BookDisplayMode.INDEX

		category("basics", "Basics", icon = Items.BOOK) {
			entryMap("w")

			entry("welcome", "Welcome", Items.PAPER, mapKey = 'w') {
				textPage {
					title = "Getting Started"
					text = "Welcome to the guide."
				}

				spotlightPage(Items.CRAFTING_TABLE) {
					text = "Craft one before continuing."
				}
			}
		}
	}
}

Register it through Modonomicon after creating your language provider:

generator.addProvider(
	event.includeClient(),
	NeoBookProvider.of(
		event,
		lookupProvider,
		GuideBookProvider(languageProvider::add)
	)
)

Category and entry objects are usable as type-safe links through ModonomiconText.categoryLink and ModonomiconText.entryLink. Entry definitions are deferred until generation, allowing links to entries declared later. Page IDs are assigned automatically, while entry-map keys, duplicate IDs, anchors, ownership, and required pages are validated before output is written. customize hooks on books, categories, and entries expose the underlying Modonomicon models for features outside the convenience DSL.

Java

Java uses the same model with ordinary constructors and a Consumer for entry contents:

@Override
public PatchouliBook buildBook() {
    PatchouliBook book = new PatchouliBook(
            "example",
            "Example Guide",
            "Welcome to the guide."
    );

    PatchouliBookCategory basics = book.category(
            "basics",
            "Basics",
            "Everything needed to get started.",
            Items.BOOK
    );

    book.entry("welcome", basics, "Welcome", Items.PAPER, entry -> {
        entry.page(new TextPage("Your first page", "Getting Started"));
        entry.page(new CraftingRecipePage(Items.CRAFTING_TABLE));
    });

    return book;
}

See ExampleBookProviderJava for a complete provider and registration example.

Installation

Add the project repository and dependency to your Gradle build. Replace VERSION with the desired published version.

repositories {
    maven {
        url = "https://maven.latvian.dev/releases"
    }
}

dependencies {
    implementation "dev.aaronhowser.mods:patchoulidatagen-1.21.1:VERSION"
}

About

A DataGenerator library mod for mod makers to create Patchouli Books with no JSON error

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages