Modding:Content Tutorial Complex Grid Recipes: Difference between revisions

From Vintage Story Wiki
m
In progress...
mNo edit summary
m (In progress...)
Line 9: Line 9:


=== Objective ===
=== Objective ===
The variant system has an extensive amount of uses. In this tutorial, we will create a set of blocks with independent textures, using two separate variant groups. These blocks will show you how you can mix variant groups together to create a huge number of new assets.
Recipes in Vintage Story are very versatile, and the grid recipe system has a number of features that have not yet been talked about. In this tutorial, you will find out how to create more complex recipes, including those with variants, different itemstack quantities, returned itemstacks, and some other smaller features.


=== Assets ===
=== Assets ===
Line 17: Line 17:


* Mod Setup & Folder Structure
* Mod Setup & Folder Structure
* Template advanced shiny block file
* Simple 'Sleek Door' recipe
* Completed lang file
* Block texture files


=== Prerequisites ===
=== Prerequisites ===
Line 25: Line 23:


* [[Modding:Developing a Content Mod|Setting up a content mod and using an IDE.]]
* [[Modding:Developing a Content Mod|Setting up a content mod and using an IDE.]]
* [[Modding:Content Tutorial Basics|The functions of shape, texture and lang files.]]


It is recommended to have completed the following tutorials:
It is recommended to have completed the following tutorial:


* [[Modding:Content Tutorial Simple Block|3. Simple Block]] - The simple block made in this tutorial is the basis for this tutorial.
* [[Modding:Content Tutorial Simple Recipe|4. Simple Recipes]] - This tutorial begins with a basic recipe.
* [[Modding:Content Tutorial Item Variants|5. Item Variants]] - This tutorial gives a good beginning stage for creating variants. These tutorials will also be formatted very similarly.


It is recommended, but not necessary, to understand the following concept:
It is recommended, but not necessary, to understand the following concept:
Line 37: Line 33:


== Navigating Assets ==
== Navigating Assets ==
Using the downloaded workspace, have a look at the mod assets that currently exist.
This tutorial is simply to create new recipes - The only file is ''recipes/grid/sleekdoor.json''. This is a simple recipe, which inputs an oak solid door and outputs an oak sleek door.<syntaxhighlight lang="json">
 
{
* ''blocktypes/advancedshinyblock.json'' - This blocktype file is from the finished [[Modding:Content Tutorial Simple Block|Simple Block]] tutorial.
"ingredientPattern": "D",
* ''lang/en.json'' - This already contains the entries needed for the tutorial.
"width": 1,
 
"height": 1,
* ''textures/block/shiny...'' - The four texture files for our blocks. Notice that we are using gold and iron textures, and both have 'damaged' states.
"ingredients": {
 
"D": {
== Defining Variants ==
"type": "block",
All work in this tutorial will be done in the ''blocktypes''/''advancedshinyblock.json'' file. Open it in your IDE and you can get started.
"code": "game:door-solid-oak"
 
}
Firstly, the item's code is still set to "''simplegoldblock"''. Change this to "''advancedshinyblock"''.
 
Before you can utilize any variant systems, you will need to define the variants for your block. To do this, use the ''"variantGroups"'' property. This is ''usually'' placed directly below the ''code'' property, but it would work anywhere in the object.
 
For this block, we are going to create two variant groups.<syntaxhighlight lang="json">
"variantgroups": [
{
"code": "type",
"states": [ "gold", "iron" ]
},
},
{
"output": {
"code": "condition",
"type": "block",
"states": [ "good", "used" ]
"code": "game:door-sleek-windowed-oak"
}
}
],
}
</syntaxhighlight>This example creates two variant groups - Named "''type''" and "''condition''". When you use more than one variant group, the game will create block codes using every permutation of those two groups.
</syntaxhighlight>
 
If you were to test the mod now, you will see that there exists four block objects with the codes:
 
* ''advancedshinyblock-gold-good''
* ''advancedshinyblock-gold-used''
* ''advancedshinyblock-iron-good''
* ''advancedshinyblock-iron-used''
Notice that the order your variant groups are defined affects the order they appear in the ID. When using variants, especially when using wildcards, this is important to remember.
 
As you probably expected by now, these blocks do not have the appropriate textures.
 
[[File:BlockVariantsContentTutorial Block all with same textures..png|frameless]]
 
== Variant-Based Textures ==
As explained in the [[Modding:Content Tutorial Item Variants|Item Variants]] tutorial, there are two ways of using variants - ''ByType'' and ''Substitution''. In this tutorial, you're going to use both methods. Before continuing, it may be a good idea to refresh yourself about how both methods work in the item variants tutorial.
 
This is the current texture property:<syntaxhighlight lang="json">
"textures": {
"all": { "base": "block/shinygoldtexture" }
},
</syntaxhighlight>This blocktype has a total of four variants - That's not many. Although you could create a ''byType'' entry for each variant code, it is a good idea to understand how you can use a mixture of the two methods. Keep in mind, similar to the item variants, there are a number of ways to achieve the final result. Feel free to experiment with other methods, variants are a complex but beautiful subject when used effectively.
 
Using the ''ByType'' suffix, you can split the texture by the condition variant:<syntaxhighlight lang="json">
"texturesbytype": {
"*-good": {
"all": { "base": "block/shinygoldtexture" }
},
"*-used": {
"all": { "base": "block/shinygoldtexture" }
}
},
</syntaxhighlight>A quick reminder of wildcards may be in order. When using the ''ByType'' suffix, each object's resolved code will start at the first key (''"*-good")'' listed and go down the list. If the resolved code matches with the given string, if will then use that key's property. Using an asterisk ( '''*''' ) in a key tells the game that ''any'' string can go here. So, in this example, here is the list of matching objects:
{| class="wikitable"
!"*-good"
|"advancedshinyblock-gold-good", "advancedshinyblock-iron-good"
|-
!"*-used"
|"advancedshinyblock-gold-used", "advancedshinyblock-iron-used"
|}
Although not used in this example, you can simply use an asterisk as a byType key to match everything. This is useful when you wish to specify a value for a single object, but have every other object use a different value.
{| class="wikitable mw-collapsible mw-collapsed"
|Why can't you use "'''*-gold'''" as a key?
|-
|Remember that the order of the variant groups is important when using wildcards. In every example where wildcards have been used, it has always been to specify the final variant. The ID of, for example, "advancedshinyblock-gold-good" does ''not'' fit within the wildcard "*-gold", as "gold" is not the final part of the code.
As such, you would have to use "'''*-gold-*'''". This will accept any string before "'''-gold-'''" as well as any string after it.
|}
''Anyway, back to the code.''
 
The given code sample doesn't actually specify a different texture for each type. Replace each texture property with a specific variant substitution.<syntaxhighlight lang="json">
"texturesbytype": {
"*-good": {
"all": { "base": "block/shiny{type}texture" }
},
"*-used": {
"all": { "base": "block/shiny{type}texture-damaged" }
}
},
</syntaxhighlight>As you can see, this uses the '''{type}''' to substitute "gold" or "iron" into the texture path. If you follow the code, you end up with these resolved texture paths:
{| class="wikitable"
!Block ID
!Resolved Texture Path
|-
|advancedshinyblock-gold-good
|block/shinygoldtexture
|-
|advancedshinyblock-gold-used
|block/shinygoldtexture-damaged
|-
|advancedshinyblock-iron-good
|block/shinyirontexture
|-
|advancedshinyblock-iron-used
|block/shinyirontexture-damaged
|}
If you are having issues getting any textures to work, it is often a good idea to create a table like this. For every ID, work out the resolved texture path, and ensure it exists.
 
If you now test your mod, you'll see your blocks working as expected!


[[File:ContentTutorialBlockVariants All Block Variants Working With Textures.png|frameless]]
== Variant-Based Recipes ==
So, you know how to make recipes. However


== Conclusion ==
== Conclusion ==
Confirmedusers
637

edits