Datapack Documentation - eerussianguy/firmalife GitHub Wiki
Firmalife's datapack support for 1.18+ is very similar to that of TFC. The docs for that are linked here and should be read as a starting point for any questions you have about these (abbreviated) docs.
Data
Firmalife has two types of non recipe reloadable data. Note how similar to how tfc data jsons go in data/your_namespace/tfc/the_thing/file.json
, firmalife data goes in data/your_namespace/firmalife/the_thing/file.json
Greenhouse Types
Greenhouse types specify what blocks are matched to what tier of greenhouse. Greenhouses are all made from one 'type' of greenhouse block. The climate station tries to match the first blocks it finds touching it to any existing greenhouse types, and from there assumes the rest of the greenhouse will follow that type. All in all, this means that you can specify greenhouses to be made out of any kind of block, provided the blocks aren't on the list of blocks for another greenhouse. The json format is as follows:
ingredient
: A Block Ingredient matching the greenhouse blocks of this type.tier
: An integer of the tier of this greenhouse. Planters must be at or above this tier to work in the greenhouse. The Firmalife values are 5, 10, 15, and 20, for wood, copper, iron, and stainless steel greenhouses. Gaps are provided for possible sub-tiers.
Note that the folder name of a greenhouse type is /greenhouse/
// reference: data/firmalife/firmalife/greenhouse/copper.json
{
"ingredient": {
"tag": "firmalife:all_copper_greenhouse"
},
"tier": 10
}
Plantable
A plantable describes something that can grow in the greenhouse. This can be thought of like a recipe -- it can turn an arbitrary item into another arbitrary item, specifying some steps along the way. Note that textures specified in here need to be manually stitched to the texture atlas, either with the TFC config option called "additionalMetalSheetTextures" (or something to that effect), or with some sort of mod, or be already stitched because they are used with a block/item already (this last bit is likely). The json format is as follows:
ingredient
: An Ingredient, specifying what is accepted as a seed for theplanter
: The string name of a planter. Currently only builtin planters can be used in this field. Possible values includequad
,large
,hanging
,trellis
,bonsai
, andhydroponic
. Defaults toquad
.tier
The minimum integer tier of the greenhouse type needed to grow this plantable (see above). Defaults to0
, which means all greenhouses take it.stages
: One less than the number of textures the planter must cycle through as it grows. For example, squash has textures 0, 1, 2, 3, 4, so this value is4
. Does not need to be specified fortrellis
planters or forbonsai
extra_seed_chance
: A float [0, 1], the chance of getting an extra seed back when finished growing. Default0.5
seed
: An item, seed returned by the crop once its picked. If not specified, no seed will be dropped. This is different than theingredient
field in order to let you specify different/empty return from planter.crop
: An item, which is guaranteed to be returned by the crop once it is picked.nutrient
: A TFC nutrient that the crop consumes. Can benitrogen
,phosphorous
, orpotassium
.texture
: An array of strings, corresponding to the textures the planter uses. This must be specified differently depending on the planter (see below). If empty, must be specified as[]
.specials
: An array of strings, corresponding to extra textures that the planter uses. This must be specified differently depending on the planter (see below). If empty, must be specified as[]
.
For planters and textures, follow these standards to make your textures work:
large
,quad
,hydroponic
: Specifytexture
in order of growth. Special textures can be[]
.hanging
: Same as above fortexture
, but inspecials
specify the fruit texture, eg["firmalife:block/crop/banana_fruit"]
trellis
: Specifytexture
in this order: growing, dry, flowering, fruiting. Special textures can be[]
.bonsai
: Specifytexture
in this order: fruiting, dry, flowering, branch, leaves. Special textures can be[]
.
Example:
// reference: data/firmalife/firmalife/plantable/peach.json
{
"planter": "bonsai",
"ingredient": {
"item": "tfc:plant/peach_sapling"
},
"seed": {
"item": "tfc:plant/peach_sapling"
},
"crop": {
"item": "tfc:food/peach"
},
"nutrient": "nitrogen",
"stages": 0,
"texture": [
"tfc:block/fruit_tree/peach_fruiting_leaves",
"tfc:block/fruit_tree/peach_dry_leaves",
"tfc:block/fruit_tree/peach_flowering_leaves",
"tfc:block/fruit_tree/peach_branch",
"tfc:block/fruit_tree/peach_leaves"
],
"specials": [],
"tier": 15,
"extra_seed_chance": 0.08
}
Some notes on standards I followed when making the builtin plants. These don't have to be followed but will make your stuff less confusing.
- For quad planters,
extra_seed_chance
for herbs it is0.8
, and the tier is usually0
(any greenhouse) - For hydroponic planters, the tier is usually
10
(copper) - For hanging planters the tier is usually
15
(iron) - For large planters, the tier is
0
(any greenhouse) for regular crops, and10
(copper) for grains - For bonsai planters, the tier is
15
(iron) and theextra_seed_chance
is 0.08 - For trellis planters, the tier is
15
(iron), theextra_seed_chance
is0
, and theseed
is not specified (and therefore empty). This is because trellis planters have a unique propagation mechanic, so duplicating them normally would break things. - I tried to follow the nutrients for all TFC crops. For bushes/fruit trees I made them take nitrogen.
Recipes
Smoking
Smoking recipes use a bit of trickery to make sure they apply/accept the right combo of food traits. Otherwise, they are easy to understand.
ingredient
: The Ingredient to be processed.result
: An Item Stack Provider to be created based on the input.
// reference: data/firmalife/recipes/smoking/meat.json
{
"type": "firmalife:smoking",
"ingredient": {
"type": "tfc:not_rotten",
"ingredient": {
"type": "tfc:has_trait",
"trait": "tfc:brined",
"ingredient": {
"type": "tfc:lacks_trait",
"trait": "firmalife:smoked",
"ingredient": {
"tag": "tfc:foods/raw_meats"
}
}
}
},
"result": {
"modifiers": [
"tfc:copy_input",
{
"type": "tfc:add_trait",
"trait": "firmalife:smoked"
}
]
}
}
Let me do a little explaining. TFC Ingredients can delegate to each other. This means most ingredients have an ingredient
field that lets them specify an ingredient that must also pass in order for this ingredient to work. The above example first checks that the item is not rotten, then that it has the trait tfc:brined
, then that it does not have the trait firmalife:smoked
, then checks that it is in the tag tfc:foods/raw_meats
.
Drying
Drying recipes are simple and need no explanation. You may wish to use a tfc:not_rotten
ingredient.
ingredient
: The Ingredient to be processed.result
: An Item Stack Provider to be created based on the input.
Oven
Oven recipes are also simple, but have extra parameters.
ingredient
: The Ingredient to be processed.result_item
: An Item Stack Provider to be created based on the input.temperature
: The minimum temperature of the top oven for the recipe to operateduration
The amount of ticks required for the recipe to finish baking.
// reference: data/firmalife/recipes/oven/barley_bread.json
{
"type": "firmalife:oven",
"ingredient": {
"type": "tfc:not_rotten",
"ingredient": {
"item": "firmalife:food/barley_dough"
}
},
"result_item": {
"item": "tfc:food/barley_bread"
},
"temperature": 200,
"duration": 1000
}
Vat
Vat recipes are similarly specified to barrel recipes, with some added parameters. It is possible to specify an invalid vat recipe, meaning that the item and fluid inputs can't be transformed with the given ratios. Take care and read the examples in the existing code.
input_item
: An Item Stack Ingredient, optional.input_fluid
: A Fluid Stack Ingredient, optional.output_item
: An Item Stack Provider, optional.output_fluid
: A Fluid Stack, optional.length
: The duration, an integer amount of ticks, default600
.temperature
: The minimum temperature, a float, default300
.jar
: Optionally, an item stack to be attached. Only used for operations that producefirmalife:fruity_fluid
in conjunction with the jarring station.
// reference: data/firmalife/recipes/vat/beet_sugar.json
{
"type": "firmalife:vat",
"input_item": {
"ingredient": {
"type": "tfc:not_rotten",
"ingredient": {
"item": "tfc:food/beet"
}
},
"count": 5
},
"input_fluid": {
"ingredient": "tfc:salt_water",
"amount": 1000
},
"output_item": {
"item": "minecraft:sugar",
"count": 3
}
}
Mixing Bowl
The mixing bowl operates very similarly to that of the TFC pot.
ingredients
: An array of up to 5 Ingredientsfluid_ingredient
: A Fluid Stack Ingredientoutput_item
: An Item Stack. Optional.output_fluid
: A Fluid Stack. Optional.
// reference: data/firmalife/recipes/mixing_Bowl/butter.json
{
"type": "firmalife:mixing_bowl",
"ingredients": [
{
"item": "tfc:powder/salt"
}
],
"fluid_ingredient": {
"ingredient": "firmalife:cream",
"amount": 1000
},
"output_item": {
"item": "firmalife:food/butter"
}
}
Pumpkin Knapping
These are exactly like regular Knapping Recipes. The type
field should be specified as firmalife:pumpkin_knapping
.