Modding:Variants: Difference between revisions

From Vintage Story Wiki
mNo edit summary
(Updates... still in progress.)
Line 7: Line 7:
[[File:HammersToShowVariants.png]]
[[File:HammersToShowVariants.png]]


== Basic Usage ==
== Usage in JSON ==
Variant groups are extremely useful for content and code modders, so it is important to know exactly how to use them in your assets.
 
=== Defining Variant Groups ===
To create a set of variants, you will need to define at least one variant group, which includes the variant ''code'', and all the ''states'' for that variant.<syntaxhighlight lang="json">
variantgroups: [
    { code: "metal", states: ["copper", "tinbronze", "bismuthbronze", "blackbronze", "gold", "silver", "iron", "meteoriciron", "steel"] }
]
</syntaxhighlight>The variant group for the hammer is shown above. The code is ''metal'', and the states are a list of metals. Each ''state'' will result in a new object, with the state ID being added onto the end of the item's code. Hammers, for example, all have a code of "''hammer-{metal}"'', where ''{metal}'' is replaced with the appropriate state.
 
An object can have any number of variant groups. Take a look at the ''seashell.json'' variant groups:<syntaxhighlight lang="json">
variantgroups: [
{ code: "type", states: ["scallop", "sundial", "turritella", "clam", "conch", "seastar", "volute"] },
{ code: "color", states: ["latte", "plain", "seafoam", "darkpurple", "cinnamon", "turquoise"  ] }
]
</syntaxhighlight>Seashells have two variant groups: t''ype'' and ''color''. For each state in ''type'', there exists every state in ''color'', giving a total of 42 different sea shells. Every sea shell in game has a code of "''seashell-{type}-{color}''".
 
On occasion, a combination of variant groups can cause the creation of unwanted objects. Say, for example, that turquoise clams were unrealistic and shouldn't be in the game. To remove variants, you can use the '<nowiki/>''SkipVariants''' property. The seashell variants would now look like this:<syntaxhighlight lang="json">
variantgroups: [
{ code: "type", states: ["scallop", "sundial", "turritella", "clam", "conch", "seastar", "volute"] },
{ code: "color", states: ["latte", "plain", "seafoam", "darkpurple", "cinnamon", "turquoise"  ] }
],
skipVariants: [
    "seashell-clam-turquoise"
]
</syntaxhighlight>Any code within skipVariants will not be created in game.
 
Sometimes, you may want to specifically choose which variants should be created in game. For example, you may only want a specific selection of seashells to be created in the game for testing purposes. To only allow specific variants, you can use the '<nowiki/>''AllowedVariants''' property. The seashell variants would now look like this:<syntaxhighlight lang="json">
variantgroups: [
{ code: "type", states: ["scallop", "sundial", "turritella", "clam", "conch", "seastar", "volute"] },
{ code: "color", states: ["latte", "plain", "seafoam", "darkpurple", "cinnamon", "turquoise"  ] }
],
allowedVariants: [
    "seashell-scallop-seafoam",
    "seashell-clam-darkpurple",
    "seashell-sundial-latte",
    "seashell-sundial-seafoam"
]
</syntaxhighlight>Any code that is ''not'' within allowedVariants will not be created in game.
 
It is important to remember that skipVariants takes presedence over allowedVariants - If an element exists in both the allowed and skip list, it will be skipped.
 
''SkipVariants'' and ''AllowedVariants'' both accept wildcard parameters, which will be spoke about soon.


=== ByType Properties ===
=== ByType Properties ===
=== {Variant Groups} ===


=== Wildcards ===
=== Wildcards ===


== Detailed Understanding ==
== Detailed Understanding ==
=== Calculating Variant Asset Locations ===
In Vintage Story, all items, blocks, and entities are loaded as ''registry objects'' ([https://github.com/anegostudios/vsessentialsmod/blob/master/Loading/RegistryObjectType.cs GitHub]). When a registry object is loaded into the game, before any other properties are read, both its code and variant properties are analysed. There exists 3 json properties to control the creation of variants, which are:
* '''VariantGroups''' - An array of all variant groups available for the object.
* '''SkipVariants''' - An array of wildcards - Any variants that match these wildcards will never be created.
* '''AllowedVariants''' - An array of wildcards - If this property exists, then ''only'' variants that match these wildcards will be created, unless they exist in the skip list.
When these arrays are loaded, the game begins to resolve the variant entries by creating unique asset locations for each variant entry. There can be numerous variant groups for any object, so every possible permutation for all the variant states is calculated. This is easy to see if we analyse the ''seashell.json'' file. <syntaxhighlight lang="json">
variantgroups: [
{ code: "type", states: ["scallop", "sundial", "turritella", "clam", "conch", "seastar", "volute"] },
{ code: "color", states: ["latte", "plain", "seafoam", "darkpurple", "cinnamon", "turquoise"  ] }
]
</syntaxhighlight>Seashells have two variant groups: t''ype'' and ''color,'' meaning that every variant of seashell will follow the code of "''seashell-type-color''". '''For every ''type'' of seashell, there exists every ''color'' of that type.''' In total, as there are 7 ''types'' and 6 ''colors'', this resolves into a total of 42 unique sea shell asset locations.
All permutations are analysed against the ''skip'' and ''allowed'' arrays, creating a populated list of every allowed code.
=== Analysing ByType & {VariantCodes} ===
When all the available variant permutations exist, all json properties are cloned for each resolved variant.
Any property in a json file can be defined as '<nowiki/>''byType''', except from the ''code'' and variant properties. The ByType properties are analysed based on the provided wildcards, and properties that do not match the variant are removed.
After the '<nowiki/>''byType''' is analysed, any variant groups referenced in curly braces ('''{ }''') are substituted with their appropriate variant state.
When all the variants, byTypes, and variant groups are resolved, the cloned json properties are loaded as a unique object.


== Conclusion ==
== Conclusion ==

Revision as of 14:53, 29 March 2024


Introduction

This page is in progress.

Basic Understanding

HammersToShowVariants.png

Usage in JSON

Variant groups are extremely useful for content and code modders, so it is important to know exactly how to use them in your assets.

Defining Variant Groups

To create a set of variants, you will need to define at least one variant group, which includes the variant code, and all the states for that variant.

variantgroups: [
    { code: "metal", states: ["copper", "tinbronze", "bismuthbronze", "blackbronze", "gold", "silver", "iron", "meteoriciron", "steel"] }
]

The variant group for the hammer is shown above. The code is metal, and the states are a list of metals. Each state will result in a new object, with the state ID being added onto the end of the item's code. Hammers, for example, all have a code of "hammer-{metal}", where {metal} is replaced with the appropriate state. An object can have any number of variant groups. Take a look at the seashell.json variant groups:

variantgroups: [
	{ code: "type", states: ["scallop", "sundial", "turritella", "clam", "conch", "seastar", "volute"] },
	{ code: "color", states: ["latte", "plain", "seafoam", "darkpurple", "cinnamon", "turquoise"  ] }
]

Seashells have two variant groups: type and color. For each state in type, there exists every state in color, giving a total of 42 different sea shells. Every sea shell in game has a code of "seashell-{type}-{color}". On occasion, a combination of variant groups can cause the creation of unwanted objects. Say, for example, that turquoise clams were unrealistic and shouldn't be in the game. To remove variants, you can use the 'SkipVariants' property. The seashell variants would now look like this:

variantgroups: [
	{ code: "type", states: ["scallop", "sundial", "turritella", "clam", "conch", "seastar", "volute"] },
	{ code: "color", states: ["latte", "plain", "seafoam", "darkpurple", "cinnamon", "turquoise"  ] }
],
skipVariants: [
    "seashell-clam-turquoise"
]

Any code within skipVariants will not be created in game. Sometimes, you may want to specifically choose which variants should be created in game. For example, you may only want a specific selection of seashells to be created in the game for testing purposes. To only allow specific variants, you can use the 'AllowedVariants' property. The seashell variants would now look like this:

variantgroups: [
	{ code: "type", states: ["scallop", "sundial", "turritella", "clam", "conch", "seastar", "volute"] },
	{ code: "color", states: ["latte", "plain", "seafoam", "darkpurple", "cinnamon", "turquoise"  ] }
],
allowedVariants: [
    "seashell-scallop-seafoam",
    "seashell-clam-darkpurple",
    "seashell-sundial-latte",
    "seashell-sundial-seafoam"
]

Any code that is not within allowedVariants will not be created in game.

It is important to remember that skipVariants takes presedence over allowedVariants - If an element exists in both the allowed and skip list, it will be skipped.

SkipVariants and AllowedVariants both accept wildcard parameters, which will be spoke about soon.

ByType Properties

{Variant Groups}

Wildcards

Detailed Understanding

Calculating Variant Asset Locations

In Vintage Story, all items, blocks, and entities are loaded as registry objects (GitHub). When a registry object is loaded into the game, before any other properties are read, both its code and variant properties are analysed. There exists 3 json properties to control the creation of variants, which are:

  • VariantGroups - An array of all variant groups available for the object.
  • SkipVariants - An array of wildcards - Any variants that match these wildcards will never be created.
  • AllowedVariants - An array of wildcards - If this property exists, then only variants that match these wildcards will be created, unless they exist in the skip list.

When these arrays are loaded, the game begins to resolve the variant entries by creating unique asset locations for each variant entry. There can be numerous variant groups for any object, so every possible permutation for all the variant states is calculated. This is easy to see if we analyse the seashell.json file.

variantgroups: [
	{ code: "type", states: ["scallop", "sundial", "turritella", "clam", "conch", "seastar", "volute"] },
	{ code: "color", states: ["latte", "plain", "seafoam", "darkpurple", "cinnamon", "turquoise"  ] }
]

Seashells have two variant groups: type and color, meaning that every variant of seashell will follow the code of "seashell-type-color". For every type of seashell, there exists every color of that type. In total, as there are 7 types and 6 colors, this resolves into a total of 42 unique sea shell asset locations.

All permutations are analysed against the skip and allowed arrays, creating a populated list of every allowed code.

Analysing ByType & {VariantCodes}

When all the available variant permutations exist, all json properties are cloned for each resolved variant.

Any property in a json file can be defined as 'byType', except from the code and variant properties. The ByType properties are analysed based on the provided wildcards, and properties that do not match the variant are removed.

After the 'byType is analysed, any variant groups referenced in curly braces ('{ }) are substituted with their appropriate variant state.

When all the variants, byTypes, and variant groups are resolved, the cloned json properties are loaded as a unique object.

Conclusion


Content Modding
Basics Content Mods Developing a Content Mod
Tutorials
Concepts Modding Concepts Variants Domains Patching Remapping World Properties
Uncategorized
Icon Sign.png

Wondering where some links have gone?
The modding navbox is going through some changes! Check out Navigation Box Updates for more info and help finding specific pages.

Modding
Modding Introduction Getting Started Theme Pack
Content Modding Content Mods Developing a Content Mod Basic Tutorials Intermediate Tutorials Advanced Tutorials Content Mod Concepts
Code Modding Code Mods Setting up your Development Environment
Property Overview ItemEntityBlockBlock BehaviorsBlock ClassesBlock EntitiesBlock Entity BehaviorsWorld properties
Workflows & Infrastructure Modding Efficiency TipsMod-engine compatibilityMod ExtensibilityVS Engine
Additional Resources Community Resources Modding API Updates Programming Languages List of server commandsList of client commandsClient startup parametersServer startup parameters
Example ModsAPI DocsGitHub Repository