Patchouli Documentation
repository·26.1·Indexed 18 days ago
https://github.com/vazkiimods/patchouliA data-driven, dependency-free documentation framework for Minecraft modders and pack makers to create in-game guides. Includes guides on adding Patchouli as a dependency for Fabric and NeoForge, using Component Processors to derive template variables, and detailed specifications for template components such as text, items, images, entities, and tooltips.
What's inside Patchouli
- Patchouli is a mod designed to provide high-quality, data-driven documentation for modders and modpack makers. It allows developers to create in-game guidebooks that are driven by data rather than hardcoded logic.
Determine an Entry ID
26.1An entry's ID is the path required to locate it starting from
/en_us/entries. For example, an entry located at/en_us/entries/misc/cool_stuff.jsonhas the IDpatchouli:misc/cool_stuff.For modders, the domain used in the ID is the domain in which the book is defined.
How Config Flags work for gating content
26.1Config Flags allow you to dynamically enable or disable content within a Patchouli book (including categories, entries, pages, or template components) based on the game environment or configuration settings.
In your book's JSON structures, you can assign a "flag" tag to an element. If the expression assigned to that flag evaluates to
false, the content is disabled and will not appear in the book. If a flag name is used that has not been defined, it defaults tofalse.Understand multiblock pattern indexing and directions
26.1When defining a
pattern, the axes follow programming conventions rather than standard cardinal directions. This is critical when placing blocks with specific properties likefacing.- Y-axis: The outer array. Index 0 is the top layer, increasing downwards.
- X-axis: The middle array. Later entries in the array move East.
- Z-axis: The characters within the strings. Later characters in the string move South.
Example for placing stairs facing different directions:
"pattern": [ [ " W ", "N S", " E " ] ], "mapping": { "W": "minecraft:oak_stairs[facing=west]", "N": "minecraft:oak_stairs[facing=north]", "S": "minecraft:oak_stairs[facing=south]", "E": "minecraft:oak_stairs[facing=east]" }Create Empty Pages (`patchouli:empty`)
26.1Empty pages can be used as spacers or for aesthetic purposes.
Fields:
draw_filler(boolean): Determines if the default page filler texture is drawn. Defaults totrue. Set tofalseto render a completely blank page.
{ "type": "patchouli:empty", "draw_filler": false }Bind variables in included templates
26.1Variables inside an included template can be resolved using the alias defined in the
askey.Default Resolution
If you include a template
asincl, and that template uses a variable#text, you access it in the parent template (or entry) using the pathincl.text.Using the
usingobject for custom bindingYou can use the
usingobject to remap variables or provide static values. This allows you to change the variable name or bind it to a parent variable.- Static Values: Set a variable to a specific string.
- Variable Rebinding: Map an included variable to a parent variable (e.g., mapping
#textin the child to#textin the parent). This allows you to use the variable directly (e.g.,text) instead of using the alias prefix (e.g.,incl.text).
"include": [ { "template": "sometemplate", "as": "incl", "using": { "text": "I'm an included template" } } ]Common attributes for all Patchouli page types
26.1Every page object within a
pagesarray in a Patchouli Entry can use the following common attributes to control visibility, locking, and internal referencing:type(String, mandatory): The namespaced ID determining the page type (e.g.,patchouli:text). In 1.17+, use fully-qualified namespaced IDs. In 1.16 or earlier, use the short name (e.g.,text).advancement(String): A resource location pointing to a Minecraft advancement. The page will only appear once this advancement is completed. Leaving it empty or omitting it keeps the page unlocked.flag(String): A config flag expression that determines if the page should exist based on user configuration.anchor(String): A unique identifier used to refer to this specific page via internal links.
Use variables in Patchouli templates
26.1You can pass dynamic data from a book entry into a template using variables.
- In the Template: Define a variable by prefixing a key with a hash symbol (e.g.,
"#text"). - In the Entry: Provide a value for that key at the same level as the
typedeclaration.
Example Template (
test_template.json):{ "components": [ { "type": "patchouli:text", "text": "#text", "x": 20, "y": 30 } ] }Example Entry:
{ "type": "yourbooknamespace:test_template", "text": "We just passed in the text from a variable!" }Constraints:
- You can define multiple unique variables (e.g.,
#upper_text,#lower_text). - Warning: You cannot use variable names that conflict with existing common keys used by Default Page Types.
{ "components": [ { "type": "patchouli:text", "text": "#text", "x": 20, "y": 30 } ] }- In the Template: Define a variable by prefixing a key with a hash symbol (e.g.,
Derive data from variables using functions
26.1Patchouli allows you to transform variable values by applying functions. To apply a function, append
->functo the variable name inside the#delimiters.Key capabilities:
- Chaining: You can chain multiple functions together (e.g.,
#item->iname->capital). - Inline Derivation: You can use derived variables directly within a string (e.g.,
This recipe produces #item->iname#.). - Logic Guards: Functions that return
trueorfalsecan be used with theguardattribute in template components to conditionally show/hide elements.
// Example of chaining: getting an item name and capitalizing it "text": "You need #item->iname->capital#"- Chaining: You can chain multiple functions together (e.g.,
Create Quest Pages (`patchouli:quest`)
26.1Quest pages allow you to create interactive objectives within a Patchouli entry. When a quest is completed, the entry in the book will display a checkmark and move to the end of the list to keep the interface clean.
Important Constraints:
- Do not place multiple quest pages within a single entry, as this will prevent the completion status from being marked correctly.
- It is recommended to use the
[turnin](/docs/reference/entry-json)feature in the entry when using quest pages.
Fields:
trigger(String): The advancement ID that must be completed to clear the quest. Leave this empty if you want the quest to be completed manually.title(String): The title displayed above the links. If omitted or empty, it defaults to "Objective".text(String): The body text displayed under the links. Supports text formatting.
{ "type": "patchouli:quest", "trigger": "minecraft:story/my_advancement", "title": "Gathering Materials", "text": "Collect 5 iron ingots to proceed." }Licensing and Jar-in-Jar bundling considerations
26.1Patchouli's original code and assets are licensed under CC-BY-NC-SA 3.0 Unported.
Licensing implications for modders:
- Normal Dependency: If you simply depend on Patchouli via your build system, there are no licensing concerns because the mod is remapped to Intermediary (or SRG for Forge) upon compilation.
- Jar-in-Jar Bundling: If you bundle Patchouli inside your mod using Jar-in-Jar, your mod will include a refmap containing raw Mojang mappings in a JSON file. If this presents a licensing conflict for your project, do not bundle Patchouli; instead, depend on it externally.
It is generally recommended to use normal dependencies rather than Jar-in-Jar to keep archive sizes smaller.
Extend an Existing Book (Pre-1.20 Only)
26.1In versions before 1.20, you can create an "extension book" that adds content to an existing book without creating a new item.
extend(String): The ID of the target book to extend (format:modid:path). For example,patchouli:coolbookextends a book located at/data/patchouli/patchouli_books/coolbook/book.json.allow_extensions(boolean): Iffalse, prevents other books from extending this book (defaults totrue).
Note: When
extendis set, all other keys in the JSON file are ignored. The extension book inherits all entries, categories, templates, and macros from the target book.{ "extend": "patchouli:coolbook" }