Skip to content

EN ‐ Datapack

costantino2000 edited this page Aug 26, 2024 · 18 revisions

The mod allows customization of some of its content through datapack, in addition to data and assets that follow the vanilla format (structures, worldgen settings, textures, etc., which can be found in the mod files).

On the Releases page, you can find an example datapack containing the mod's custom data.

Server Language

In general, both for the researcher’s dialogues and for the structure books and signs, the data is divided into folders by language, allowing to choose a language even for content that would not normally depend on the game's language, since their texts are encoded in the level's data.

This language depends on the serverLanguage option in the main config of the mod, and as the name of the setting suggests, it is the same throughout the server and does not depend on the language of individual players, as the text is encoded within the researchers/books/etc.

Researcher Dialogues

All researcher dialogues are added by data. They can be found in the folder data/<minecraft/growsseth/etc>/growsseth_researcher_dialogue/, and are in jsonc format (JSON with comments allowed). (In the future, if other NPCs are added, the folder will be changed).

Each file has a structure like this:

{
    "shared": [
        DialogueEntry,
        DialogueEntry...
    ],
    "<event 1>": [
        DialogueEntry,
        DialogueEntry...
    ],
    "<event 2>": [
        DialogueEntry,
        DialogueEntry...
    ],
    ...
}

Each event can be one of the events in Dialogue Events, while "shared" is a special event used to define dialogues that can be reused in more events (see Shared Event or Dialogue Entry Format).

Dialogue Events

The events can be one of the following, at the time of writing (Aug 15, 2024):

General Events

Event Description Parameter
playerArrive Player arrives within NPC's range.
playerArriveNight Same as playerArrive, but at night (priority).
playerLeave Player leaves from range and sight of the NPC.
playerLeaveNight Same as playerLeave, but at night (priority).
playerArriveSoon Player arrives within 10 seconds of the last greeting (priority).
playerLeaveSoon Player leaves dialogue range after a playerArriveSoon event.
playerArriveLongTime Player arrives after over 6 hours (in-game time) from the last greeting (priority).
playerArriveNewLocation Player arrives for the first time to a new tent.
tickNearPlayer Triggers as soon as the player is near the NPC, even if already greeted.
hitByPlayer After being hit by the player.
lowHealth When health falls below a certain amount.
death Upon death.
rename After being renamed by the player. New name.
playerAdvancement A player achieves an advancement and is within range. Advancement ID.
global Dialogues triggered in every event (use in specific cases).

Researcher Events

Event Description Parameter
makeMess Breaking blocks "useful" for the researcher (writing, cartography).
fixMess Replaced blocks broken by makeMess.
refuseTrade Attempted to trade while the researcher is angry and refuses it.
breakTent Breaking of low-value tent blocks.
borrowDonkey Donkey borrowed.
returnDonkey Donkey returned.
exploreCellar Player enters the secret area in the cellar.
exitCellar Player exits the cellar.
hitByPlayerImmortal Like hitByPlayer, but only if the researcher is immortal.
playerCheats When the player triggers the anticheat while fighting (if active).
killPlayer When the researcher kills the player who attacked it.
playerArriveAfterKilled Like playerArrive, but only once upon arrival of a player who was killed.

The following event contains spoilers about the researcher's quest:

Show spoiler
Event Description
borrowDonkeyHealed Donkey borrowed after curing the researcher at the end of the quest.

Shared Event

shared is special and contains dialogues that can be reused in the dialogue event lists, in this way:

"shared": [
    {
        "id": "shared-dialogue-id",
        "content": "Hello!"
    }
],
"<event>": [
    ...
    {
        "id": "shared-dialogue-id",
    },
    ...
]

It's mainly useful for dialogues reused in multiple events to cover more triggers.

Dialogue Entry Format

The dialogues are represented in dialogue files and, if sent by Egobalego at Home, as JSON objects with this format:

{
    // Required fields
    "content": list | string | object, // see below
    
    // Fields required only if the "useLimit" field is present, or for shared dialogues
    "id": string,

    // Optional fields [and accepted default values]
    "immediate": true/false, // Activate the dialogue immediately, skipping any queues
    "data": object[string, string], // Custom data that can be used differently by various NPCs (see below)

    // Optional fields, only for files [no remote dialogues]
    "weight": float = 1.0, // Weight of the dialogue in the random choice
    "useLimit": int, // Usage limit for this specific dialogue
    "afterRepeatsMin": int, // Minimum number of event triggers before the dialogue can be played again
    "afterRepeatsMax": int, // Same as above, but maximum number
    "afterCloseRepeatsMin": int, // Minimum number of event triggers within a short period of time before the dialogue can be played again
    "afterCloseRepeatsMax": int, // Same as above, but maximum number
    "requiresQuest": string, // Quest required to trigger the dialogue (currently not necessary, as each NPC has at most one associated quest)
    // Quest (currently needs to look at the class in the code to see the valid quest stage values)
    "requiresQuestStage": string, // Name of the required quest stage (e.g., "start", "home", etc. for the Researcher)
    "requiresUntilQuestStage": string, // Same as above, but instead of requiring the stage, it disables the dialogue from that stage onwards
    "requiresEventParam": string. // Some events have an associated parameter (e.g., the name in RENAME): activated only with this parameter, if left empty it will activate with every parameter
    "priority": int, // If there are more dialogues that can be activated, select only between those with the highest priority
}

The content field represents the actual line or lines of dialogue and can contain a list, a string, or an object, in one of these three formats:

"content": "LINES\nSEPARATED BY\nNEWLINES"
"content": {
    "content": "SINGLE LINE WITH PARAMETERS",
    "duration": 2.0 // seconds
}
"content": [
    "SIMPLE LINE",
    {
        "content": "LINE WITH PARAMETERS, CAN MIX BOTH",
        "duration": 1.0
    }
]

The data field is intended for use in case we'll add other NPCs with dialogues, to be used for specific things about that NPC. Currently, for the researcher, it can contain:

data: Researcher

"data": {
    "sound": "angry"/"none", // If set, uses the sound of the angry villager or no sound instead of the default one when speaking
    "madeMess": true, // If set, uses the dialogue only if the researcher is angry about players breaking his work tools in the tent
    "singleOnly": true, // If set, uses the dialogue only in Single Researcher mode
}

As shown before, a DialogueEntry can also contain only the id field; in that case, the dialogue will use the shared dialogue with the same id if present (an error will be thrown otherwise).

Researcher Trades

The researcher's trades are also defined using JSON. They are located in the folder data/<minecraft/growsseth/etc>/growsseth_researcher_trades/<en_us/it_it>/, and are in jsonc format (JSON with comments allowed).

Each file can contain Trade objects in various lists and sublists with different meanings, explained below and shown in the example file.

{
    // Trades always present in the list when in random trades mode
    "fixedTradesWhenRandom": [ ... ],
    // Trades unlocked when a structure is "available" from the researcher.
    // Mainly maps, but also, for example, the enchanting table dictionary
    "beforeStructure": {
        "structurename": [ ... ],
        "structurename2": [ ... ],
    },
    // Trades unlocked after finding a structure, ONLY in progress mode
    "progressAfterStructure": { <like beforeStructure> },
    // Trades unlocked after finding a structure, ONLY in random mode.
    // A number between these trades is chosen based on the config, and are
    // randomly chosen among them.
    "progressAfterStructureRandom": { <like beforeStructure> },
    // Possible trades in random mode, number chosen based on config
    "randomPool": [ ... ],
    // Trades unlocked in GM mode when the specified structures are active
    "unlockableByRemoteStructure": { <like beforeStructure> },
    // Trades unlocked in GM mode when the specified events are active
    "unlockableByRemoteEvent": { <like beforeStructure> },
}

For "progress mode", "random mode", and "GM mode", we refer to the options of the mod singleResearcher, singleResearcherProgressTrades, and webTrades, explained in the config.

Trade Format

Represents a single trade.

{
    "gives": { //output
        TradeItemEntry
    },
    "wants": [ //input, 1 or 2 entries
        TradeItemEntry,
        TradeItemEntry
    ],
    "priority": 50, // optional, defaults to 0, higher values will make it go higher in the list
    "noNotification": false, // optional, defaults to false, if true does not notify the new trade
    "replace": false, // optional, defaults to false, if true replaces other trades with lower priority offering the same item
    "maxUses": 1, // optional, defaults to 1, maximum uses for this trade, which is refreshed based on settings (ignored and always infinite for trades made via game-master/web)
    "randomWeight": 1.0, // "weight" of the trade if present in a list of trades chosen randomly (higher = more likely to appear)
}

TradeItemEntry Format

Objects used in trades.

{
    "id": "minecraft:stick", // game object id
    "amount": 5, // optional, default 1
    "map": TradeMapInfo, // optional, requires minecraft:filled_map or growsseth:ruins_map object, map data
    "mapPool": [ // optional, like above but more map data to choose from randomly
        TradeMapInfo,
        TradeMapInfo...
    ],
    "bookId": "enchantment_dictionary", // optional, diary id for selling one of the configured template books (object must be a writable or written book)
}

BookId refers to the book templates explained in the next section.

TradeMapInfo Format

Data for maps in trades.

{
    "structure": "#minecraft:stronghold", // structure ID or #tag to search, and used to determine map icon
    "name": "Guide Map", // Displayed name
    "description": [ // optional, can also be single string instead of list of strings
        "Line 1",
        "Line 2",
    ],
    "x": 535, // optional, x coordinate to point to (otherwise searches for a structure with the corresponding ID in worldgen)
    "z": 535, // same as above, for the z coordinate
    // optional, ID of the fixed spawn of the structure to point to (for example, structures preset via webapp or in Growsseth mode)
    "fixedStructureId": "growsseth:researcher_tent",
    // Optional, 1 or more jigsaw element IDs the structure must contain to be found
    // For example, specific houses of villages
    "searchForJigsawIds": [
        "growsseth:village/desert/desert_golem_house",
        "growsseth:village/desert/desert_golem_house_zombie"
    ],
    "scale": 3, // optional, default 3, map scale
    // Optional, icon to use instead of the structure one
    // Find vanilla icons on the wiki: https://minecraft.wiki/w/Map#Map_icons
    // And Growsseth ones in the subsection that follows
   "overrideMapIcon": "growsseth:icon_golem_house", 
}

For maps, at least one method is needed to get the structure position. The logic is as follows:

  • If x and z are specified, that position is used
  • If fixedStructureId is specified and there is a corresponding structure among the "fixed" structures (website/Growsseth mode), that position is used
  • Otherwise, a structure corresponding to the one present in the structure field (and any conditions like searchForJigsawIds) is searched for, and if it's not found the map is not sellable.

Growsseth Icon IDs

These are the map icon IDs of Growsseth, usable for overrideMapIcon in maps.

ID
"growsseth:icon_beekeeper_house"
"growsseth:icon_cave_camp"
"growsseth:icon_golem_house"
"growsseth:icon_enchant_tower"
"growsseth:icon_forge"
"growsseth:icon_conduit_ruins"
"growsseth:icon_conduit_church"
"growsseth:icon_noteblock_lab"

Template

The texts contained within the structures and in some features of the mod (researcher's diaries, some trades) are also configured by datapack, primarily to modify them more easily and allow localization in multiple languages for texts that would otherwise be fixed (as they are coded into the structures).

Book Templates

Book templates are located in the folder data/<minecraft/growsseth/etc>/growsseth_templates/book/<en_us/it_it>/. Templates can be placed in subfolders, and the researcher_diary and structures folders are used in a special way by the mod.

In general, a template can be tested with the command /booktemplate @p <ID>, where depends on the path. For example, a template placed in data/growsseth/growsseth_templates/book/en_us/researcher_diary/golem_house.json can be obtained with /booktemplate @p growsseth:researcher_diary/golem_house. You can also use /booktemplate list to get a list of available templates.

The researcher_diary folder is used to generate the diaries that the Researcher places on his lectern when a player returns from discovering a structure. The file name must correspond to the path tag of a structure in the mod (for example, #growsseth:abandoned_forge becomes abandoned_forge.json), and the diary will be placed after the player finds a structure in the tag.

The structures folder is used for books inside structures. If a book contains only one page and its text starts with %%TEMPLATE%%, the rest of the page will be used as the book ID to search for inside the folder. For example, placing a book in a chest of a structure whose only page contains %%TEMPLATE%% enchant_tower will transform the book with the content of structures/enchant_tower.json.

A book file has the following format:

{
    "name": "Burnt Diary", // Title, mandatory for signed books
    "author": "Mario", // Author, defaults to ??? if not set in signed book
    "pages": [
        // Simple text
        "Hello, this is a page\nSo I went to the next line!",
        
        // Complex text, uses Minecraft JSON text format:
        // https://minecraft.wiki/w/Raw_JSON_text_format
        {
            "type": "component",
            // After it content goes the complex text.
            // It can be a JSON object or a JSON list, follow the wiki format!
            "content": [
                {
                    "text": "What a strange writing:\n\n\""
                },
                { "text": "This text is in enchanting table language!", "font": "minecraft:alt" },
                { "text": "\"\n\nStrange, huh?" }
            ]
        },
    ]
}

Sign Templates

Sign templates are located in the folder data/<minecraft/growsseth/etc>/growsseth_templates/sign/<en_us/it_it>/. Both regular signs and hanging signs are supported.

To set a template on a sign within a structure, write %TEMPLATE% (it's different from books to fit on hanging signs) on the first line of the face or faces where you want to make the template appear, and the ID on the following lines (if the ID spans multiple lines, they are concatenated to form the complete ID).

The ID is read from the second to the fourth line. For example, a sign with the following lines on the back:

"%TEMPLATE%"
""
"church_"
"1"

will load the template "church_1" on the back of the sign when the structure is generated.

The templates have the following format:

{
    "entries": [
        // Simple text
        "Test 1",
        // Blank line
        "",
        // Complex text, as with books, uses MC's JSON text format:
        {
            "type": "component",
            "content": {"font":"minecraft:alt", "text":"Enchant language"}
        }
        // The remaining line will stay blank
    ],
    "glowing": true,    // If present, the sign face will have the glow ink effect
    "color": "red"      // The color of the text on the sign face (if absent, it will be black). The available colors are:
                        // "white", "orange", "magenta", "light_blue", "yellow", "lime", "pink", "gray", "light_gray", "cyan", "purple", "blue", "brown", "green", "red", "black"
}

Note: If you want to make the signs uneditable, you must wax them in-game before saving the structure.