Custom Terrain Tutorial planning

The place to post your WML questions and answers.

Moderator: Forum Moderators

Forum rules
  • Please use [code] BBCode tags in your posts for embedding WML snippets.
  • To keep your code readable so that others can easily help you, make sure to indent it following our conventions.
User avatar
Alarantalara
Art Contributor
Posts: 786
Joined: April 23rd, 2010, 8:17 pm
Location: Canada

Custom Terrain Tutorial planning

Post by Alarantalara »

Since there seems to be a general lack of understanding of terrain related WML, it seemed worth trying to get a reasonably coherent tutorial. In the interests of getting feedback, I'm making this a forum post instead of a wiki page. For now, I'm starting with an overview that should hopefully describe the various pieces and how they connect. I assume at least some knowledge of WML, including the basics of how to create an add-on. Links to later parts will be slowly added at the end of this overview.

A terrain in Wesnoth consists of two parts: a [terrain_type] tag and a [terrain_graphics] tag.
The [terrain_type] tag names the terrain and describes how units behave on it as well as its appearance in the editor and minimap.
The [terrain_graphics] tag controls the appearance of the terrain on the main map.
Both are optional. The impassable overlay has a terrain_type tag but no terrain_graphics tag, while the {ANIMATED_CAMPFIRE X Y} macro translates into a terrain_graphics tag without a terrain_type tag.

In addition to the above tags, there is a third top-level tag, [editor_group], that should be used for any add-on containing terrain tags. It provides a button on the right panel of the map editor so that you can place your terrain without interfering too much with core and other add-on terrain.

The basic structure of an add-on using custom terrain has two parts not present in other add-ons.

Part 1)
A section for making the terrain work in the map editor. Most of this is not needed by mainline, but the core editor groups may be found in data/core/editor/editor_groups.cfg. You will generally include this content in your _main.cfg file.

Code: Select all

#ifdef EDITOR
[binary_path]
    path=data/add-ons/<add-on name>
[/binary_path]
[editor_group]
    id=<add-on name_editor>
    name= _ "Add-on Name"
    icon="group_custom"
[/editor_group]
{~add-ons/<add-on name>/<name of cfg file containing terrain/terrain graphics tags>.cfg}
#endif
Note: While the icon key is a reference to a set of images, the path is currently hard-coded, so you really only have the choice of "group_custom", or if using 1.9, "group_custom2" and "group_custom3". You could also use the ones for the core tiles, but it's probably confusing should other people try to use them.
Note 2: The terrain graphics file will also need to be included outside of the editor as well, just like any other file containing WML you want to use. If you are creating a campaign, this would be in the same #ifdef as the scenarios. If you are creating somethign for multiplayer, then it of course goes inside #ifdef MULTIPLAYER. You will also need to include the contents of the binary path tag if it's not already present.

Part 2)
A section containing a description of the terrains. In mainline, because of the number of terrains involved, this part is split into two files, one for the terrain_type tags and one for the terrain_graphics tags. The cfg files have the names terrain.cfg and terrain_graphics.cfg and are in data/core. If you have only one or two custom terrains, it is reasonable to include both in one file.

Each terrain should have its editor group key set to the id of the editor group you defined in part 1.

Part 3)
This is really part 2 repeated in a different place. It is not needed to make any terrain work but can sometimes simplify things.
The [terrain_graphics] tag can also be a scenario level tag. If it is used within a scenario, then the tag is applied only to that scenario. This means that you can define the appearance of a terrain differently for one scenario. If you have used the animated campfire macro, then you have taken advantage of this feature. It is useful for set pieces like the campfire and changing the appearance of a terrain for one scenario (useful if you want to reuse maps). For those with big plans, To Lands Unknown uses this for the large set pieces in its scenarios.

Where to go from here:
For those who can't wait for the next installment, I have included some sources of information that should be useful.

The ReferenceWML page contains decent information for each of the three tags.

Ayin has written a tutorial for the terrain_graphics tag. While it was written for 1.2 or earlier, the tag has not changed a lot and still provides a very good overview. It was updated for 1.4 on the wiki here, which changes the terrain codes and map key to match the current format. However, for many terrains, the macros included in the terrain_graphics folder cover everything you will need in a simpler form.

The terrain_graphics.cfg file has many examples of how to use the macros.

Topics:
Creating a simple overlay terrain (like the windmill, but without animation).
Optional terrain macro parameters
Units and [terrain_type]
Base Terrains and Transitions (includes notes on choosing terrain strings)
The [terrain_graphics] tag
Images in [terrain_graphics] (includes complete layering rules)
The map Key
Terrain macros
Rotations

(other suggestions)
Last edited by Alarantalara on July 19th, 2015, 5:06 pm, edited 17 times in total.
Reason: Added link to the incomplete macros post
User avatar
doofus-01
Art Director
Posts: 4122
Joined: January 6th, 2008, 9:27 pm
Location: USA

Re: Custom Terrain Tutorial planning

Post by doofus-01 »

I just want to give a thumbs up to this initiative.
A couple of things:
1. I found the ascii maps to be somewhat confusing, despite the tutorials. That is probably worthwhile to spend some time explaining. Base, center, layer ...
2. Multi-hex terrain graphics are annoying to figure out. It requires the "artist" to be a "scriptist" as well. If there were some way to split the two tasks... I tried, for the castles, but it could have been better. And the animated water - Aye!
3. I can say that terrain macros are scary because there are so many of them, but understanding the "PLF" parts isn't so bad once you understand the base macros, so it is not quite as daunting as it might look at first.
BfW 1.12 supported, but active development only for BfW 1.13/1.14: Bad Moon Rising | Trinity | Archaic Era |
| Abandoned: Tales of the Setting Sun
GitHub link for these projects
User avatar
pyrophorus
Posts: 533
Joined: December 1st, 2010, 12:54 pm

Re: Custom Terrain Tutorial planning

Post by pyrophorus »

Hi !
IMO, this howto is a great idea.

I would suggest one more topic.
Creating a custom terrain is rather straightforward, I think.
In my experience, it's much more difficult to make one which melts smoothly with neighbour hexes.
I had a hard time to achieve that and I don't pretend I have really understood how it works !

I think you should give many working examples.

LS
alluton
Posts: 420
Joined: June 26th, 2010, 6:49 pm
Location: Finland

Re: Custom Terrain Tutorial planning

Post by alluton »

Well this helped little and is surely helpfull for beginners anyway good thread.
"This game cured me of my real life addiction."
-Flameslash
User avatar
em3
Posts: 342
Joined: April 1st, 2009, 8:59 pm
Location: Poland

Re: Custom Terrain Tutorial planning

Post by em3 »

Alarantalara wrote:A terrain in Wesnoth consists of two parts: a [terrain] tag and a [terrain_graphics] tag.
The [terrain_type] tag names the terrain and describes how units behave on it as well as its appearance in the editor and minimap.
The [terrain_graphics] tag controls the appearance of the terrain on the main map.
So , the first tag is [terrain] or [terrain_type] (emphasis mine)? :hmm:
ride on shooting star
User avatar
Alarantalara
Art Contributor
Posts: 786
Joined: April 23rd, 2010, 8:17 pm
Location: Canada

Creating an Embellishment

Post by Alarantalara »

Version 1.9 of Wesnoth introduces embellishments, terrains that add flavour to a map but don't affect game play. They are also the simplest type of terrain you can create if restricted to a single image.

As an example, I shall turn the signpost that appears on several maps into a terrain rather than an item so that it may be placed on the map using the editor.

1) Write the infrastructure needed to create terrains.

Code: Select all

#ifdef EDITOR
[editor_group]
    id=terrain_tutorial
    name= _ "Terrain Tutorial"
    icon="group_custom3"
[/editor_group]
#endif
Because my image appears in the core data files, I don't need any binary paths for this add-on.

2) Define the terrain.

Code: Select all

[terrain_type]
    symbol_image=../scenery/signpost
    editor_name= _ "Signpost"
    editor_group=terrain_tutorial
    id=tutorial_signpost
    string=^Esz
    aliasof=_bas
[/terrain_type]
This is the absolute minimum set of values required to generate a terrain that will display nicely in the editor and work in game.
symbol_image provides an image for you to see in the minimap and editor palette. It also becomes the appearance of the brush when you select it in the editor. The image path is relative to the images/terrain directory of either your add-on or core. In this case, since the image is already present in scenery, we have to go up a level first to find our image. Finally, the image name must not include the ".png" extension as the engine will add it.

editor_name provides a name that is displayed in the editor to help you identify it. It will not appear while playing a scenario. For an embellishment, that's what we want.
editor_group is the list of palettes we want our terrain to appear in. For custom terrain, this should be the id of the group from part 1.

id is a required tag for the game to keep track of the terrains. Any unique value can go here as it isn't used anywhere else.

For our purposes, string is the real id for this terrain. It is the value that identifies the terrain on the map and it is used in [terrain_graphics] rules to match terrain on the map. Selecting a good value for this key is very important. For custom embellishments, follow these rules.
  • Start it with a ^ to mark that it is an overlay terrain. There are two types of terrain: base and overlay and each hex on the map can have only one of each. Base terrains have no prefix, while overlay terrains start with a ^. Terrains like swamp, water, and grass are base terrains and we want to be able to put our embellishment on top of these, so we must make this terrain an overlay terrain.
  • Make the second character an E to mark it as an embellishment. While you could use other letters, because many terrain_graphics rules in mainline use this letter to help with transitions between terrains, you could get unexpected results. Also, the ambush and concealment special abilities also care about this value
  • Make it unique. While this example only defines one terrain, if you have multiple terrains, you must give each terrain a different string since the game uses this to identify the terrain on the map
  • Include a "y" or a "z" somewhere. These two letters are reserved for user made content, so including one lets you be certain you haven't accidentally used the same code as a terrain in mainline.
  • Make it at most 5 letters long, including the ^ at the beginning.
  • Use only letters and the characters \|/ after the ^.
aliasof interacts with a unit's movetype to determine movement costs and defense. Because this is an embellishment, we want the result to be the same as the base terrain and so we set it to the special value "_bas", which stands for whatever the base terrain is for this overlay terrain.

3) Describe the appearance of the terrain on the map
If you were to copy the two pieces of code so far and put them into the _main.cfg of any add-on, you will find a working terrain in the map editor. You can select it and draw with it on the map. However, the appearance of the map will not change. For that, a [terrain_graphics] tag or macro is required.
Signpost in palette
Signpost in palette
Palette.png (12.84 KiB) Viewed 12119 times
No image on map
No image on map
InvisibleTerrain.png (39.49 KiB) Viewed 12119 times
For an embellishment, we can use a single macro.

Code: Select all

{OVERLAY *^Esz (../scenery/signpost)}
This is the simplest form of the macro to draw overlay terrain. It has only two arguments: the terrain to match and the image to draw.
For this example, we want to match any base terrain that has our overlay terrain on it, so we use a * for the base, a ^ to mark the overlay and then the rest of the terrain string we picked for our terrain. We then specify the image in the same way we did for the symbol_image in the [terrain_type] tag. For this simple embellishment, they are the same, but the image here can be any image.

With this addition, we have a complete terrain definition that can be used on any map, even one not part of the add-on. For your own terrain, you should place the code from parts 2 and 3 in a separate file and include it if either the editor is running (EDITOR is defined) or it is in the context of your add-on (MULTIPLAYER or your campaign's define is defined).
The final terrain
The final terrain
SignpostTerrain.png (34.71 KiB) Viewed 12119 times
Complete code for example:
While this terrain works properly, it does not provide anything other than easier placement of an image when compared to using an item tag in the scenario to place the signpost (which is what Heir to the Throne does). There are also one or two problems that you will discover if you experiment with this code: the signpost does not appear when you place it in a swamp (this problem does not occur in 1.9.9 or later) and very large images get clipped.

For the next part, I will extend the simple terrain definition above to create more interesting and complex embellishments including randomly selected images, composing multiple images, and animated terrain. I will also explain why the signpost from this part does not appear in the swamp. These extensions will make TerrainWML more useful than just a limited form of an [item] tag.
Last edited by Alarantalara on November 6th, 2014, 2:05 am, edited 6 times in total.
Reason: update for new version of Wesnoth
User avatar
Alarantalara
Art Contributor
Posts: 786
Joined: April 23rd, 2010, 8:17 pm
Location: Canada

Re: Custom Terrain Tutorial planning

Post by Alarantalara »

em3 wrote:
Alarantalara wrote:A terrain in Wesnoth consists of two parts: a [terrain] tag and a [terrain_graphics] tag.
The [terrain_type] tag names the terrain and describes how units behave on it as well as its appearance in the editor and minimap.
The [terrain_graphics] tag controls the appearance of the terrain on the main map.
So , the first tag is [terrain] or [terrain_type] (emphasis mine)? :hmm:
That would be [terrain_type]. It was [terrain] in 1.6 and earlier, so I may make the occasional mistake regarding its name. This one is now fixed.
User avatar
Alarantalara
Art Contributor
Posts: 786
Joined: April 23rd, 2010, 8:17 pm
Location: Canada

Optional macro parameters

Post by Alarantalara »

Several macros have four optional parameters: probability, layer, flag, and builder. These may be combined to create several useful effects.

To add one of these parameters to a macro, append a _ followed by the first letters of the parameters you want to add in the order listed above. So to change the layer and flag of an overlay, the correct form is OVERLAY_LF.

When the game engine wants to draw the contents of a hex, it performs the following actions (simplified for clarity).
1) Examine every [terrain_graphics] tag in the order they occur and see if it applies to this hex. If it does, make a note of the image to draw.
2) Draw each image in order.
The first three parameters can affect this process.

From now on, I will call the contents of the [terrain_graphics] tags terrain rules because I find it more natural to think of rules as applying than tags.

Selecting which images to display
probability causes the terrain rule to randomly apply. Specifically, the rule applies probability percent of the time. If you have two rules that affect everything on the map, each with probability 50, then about 25% of the map will be affected by both rules, 25% by the first rule only, 25% by the second rule only and 25% by no rule. This means that if you have two images you want to choose between for a terrain, you should sometimes see one image, sometimes the other, sometimes both, and sometimes neither. However, if you try this with the OVERLAY_P macro, what you actually get is that 50% are affected by the first rule, 25% by the second, and 25% by neither. Clearly, something else is affecting the results.

That something is the flag parameter. All of the macros specify a flag even if you do not include one. Each macro requires that a rule that went before it has not set its flag for that hex and also sets that flag so that no other rule using that flag will apply. The OVERLAY macro uses the flag "overlay" by default. With this addition, the results of the OVERLAY_P macro make sense:
The first rule is examined and applied 50% of the time. If it does, then it sets the "overlay" flag.
The second rule is examined. If the "overlay" flag is set, then it does not apply, so it applies 50% of the time the first flag did not apply, or 25% of the time. It also sets the "overlay" flag if it applied.
The remaining 25% of the time, neither rule applied, the "overlay" flag was not set and no image was drawn.

Now, if the second rule applies 100% of the time, then it would be drawn for the other 50% and you get to see one image chosen randomly on each hex. Similarly, if you want each image to appear 1/3 the time, then the first rule should have probability 33, the second 50, and the last 100.

Example:
Assuming that we have created a new [terrain_type] with the terrain string "^Esbz", we can draw one of the two straw bales from the collection of item images with the following code.

Code: Select all

{OVERLAY_P *^Esbz 50 (../items/straw-bale1)}
{OVERLAY   *^Esbz    (../items/straw-bale2)}
If selecting between variant images with equal probability is the only extra part you want, then there is also the random version of the same macros, e.g. OVERLAY_RANDOM. You must name the first image the same as what you put in the image part, then add the numbers 2, 3, 4, .. up to 9 for the remaining images.

In some cases you will want to be able to draw more than one image on the same tile. This is where the flag parameter becomes useful. By picking a different flag, your macro will no longer be made to not apply by other macros, letting you draw a second image on the same hex. You will find this used in several places in mainline, including for the clouds and peaks of impassable mountains. In 1.9.8 and earlier, the swamp used an OVERLAY macro to place the grasses, which prevented the core embellishments from being drawn.

So multiple images can be drawn if different flags are set. In fact, for the embellishments we have been examining so far, a second image has to be drawn to provide a background for our image. Now the order the images are drawn cannot depend on the order the rules appear, since we can't insert our rules into the middle of the ones defined in the core files, so we need another way to define the order that the images are drawn. This method is called the layer system.
Each image from a terrain rule is assigned a layer. The images are then drawn from the bottom layer up to the top. The bottom layer is layer -1000 and the top layer is layer 1000. Units are drawn on layer 0. There is another component to this system that makes units appear in front of some layer 0 images and behind others, but we will ignore it for now. For a single hex image using the macros, the unit will always be on top of a layer 0 image. By default, overlays like our embellishments at layer 0. If we want it to appear on top of units, we can set this to a higher number like 1. We can also look up the layers of objects in terrain_graphics.cfg if we want our image to appear in front or behind something from mainline.

Animation
The final builder parameter allows you to create some simple animations. It is available in 1.9 and later. To use it, you simply include the name of the builder macro you want to use to create the animation. Unfortunately, it is very limited as the only animation lengths available are those used in mainline. This means that you have only 8 choices for your animation without defining your own macro.
These are:
ANIMATION_03: 3 frames, 200 ms per frame
ANIMATION_04: 4 frames, 100 ms per frame
ANIMATION_04_140: 4 frames, 140 ms
ANIMATION_06_150: 6 frames, 150 ms
ANIMATION_10: 10 frames, 100 ms
ANIMATION_15: 15 frames, 110 ms
ANIMATION_15_SLOW: 15 frames, 150 ms
ANIMATION_18_70: 18 frames, 70 ms

Since your animation probably won't be ideally suited to one of these lengths/durations, you can also define your own builder macro for animation that will greatly increase your options.
Define it as follows:

Code: Select all

#define MACRO_NAME IMAGESTEM POSTFIX
{ANIMATION_$$_INTERNAL {IMAGESTEM} {POSTFIX}.png @@@}#enddef
MACRO_NAME can be whatever you like
$$ with the number of frames as a two digit number that is less than or equal to 18 (e.g. 02, 12)
@@@ is the duration of a single frame

An example for a 7 frame animation with each frame lasting 90 ms with an embellishment that uses it:

Code: Select all

#define EXAMPLE_ANIMATION IMAGESTEM POSTFIX
{ANIMATION_07_INTERNAL {IMAGESTEM} {POSTFIX}.png 90}#enddef

{OVERLAY_B *^Eggz EXAMPLE_ANIMATION spinning_egg}
If you use the builder to add an animation you must also follow some rules for naming your images.
Each image has any name you like, followed by "-A##.png", where ## is a two digit number starting at 01 and going to a maximum of 18. The starting name must be the same for all images. (It's actually slightly more complicated, but the extra details only matter for transitions, which we haven't covered yet.) Finally, the name of the image must not have a space in it, as these macros are not protected from splitting parameters.
From these rules, we see that the example above would need these images: spinning_egg-A01.png, spinning_egg-A02.png, spinning_egg-A03.png, spinning_egg-A04.png, spinning_egg-A05.png, spinning_egg-A06.png, spinning_egg-A07.png

Conclusion
Up to now, we have only been using the OVERLAY macro. If you examine the macro definitions, you will discover that the only differences between OVERLAY, TERRAIN_BASE, and KEEP_BASE, as well as VILLAGE in 1.8, are the default values for these four optional parameters. These macros are provided to prevent accidental mistakes in defining the graphics for a terrain. Therefore, you should use the one that corresponds to the type of terrain you are making and modify it to match any extra needs you may have.

For the next section, we return to the [terrain_type] tag and take a closer look at how it interacts with units. With this, you will be able to duplicate the functions of all mainline terrain and a bit more.
User avatar
Alarantalara
Art Contributor
Posts: 786
Joined: April 23rd, 2010, 8:17 pm
Location: Canada

Units and [terrain_type]

Post by Alarantalara »

Up to now, the [terrain_type] tags in these tutorials have been the minimum needed to create working terrains. However, there are many more keys associated with the tag and many of them need fuller explanation.

Movement and defense
Let's look at a typical [movetype] from the core units.cfg.

Code: Select all

[movetype]
    name=smallfoot
    [movement_costs]
        shallow_water=3
        reef=2
        swamp_water=3
        flat=1
        sand=2
        forest=2
        # additional movement costs omitted
    [/movement_costs]

    [defense]
        shallow_water=80
        reef=70
        swamp_water=80
        flat=60
        sand=70
        forest=50
        # additional defenses omitted
    [/defense]

    # resistances omitted
[/movetype]
There are references to various terrains by name, like reef, flat, and sand.
If we look at a [terrain_type], the source of these names is revealed to be the id of the [terrain_type].

Code: Select all

[terrain_type]
    symbol_image=sand/beach
    id=sand
    name= _ "Sand"
    editor_name= _ "Beach Sands"
    string=Ds
    editor_group=desert
[/terrain_type]
So if we want to create an entirely new type of terrain, with our own custom movement costs, all we have to do is add a new [terrain_type] id to the [movement_costs] and [defense] sections of every [movetype] that is used in our add-on.

But what if we want to make our terrain behave the same as an existing one? There are 189 [terrain_type]s in mainline in 1.10, yet only a few are mentioned by id in the [movetype] definition. Notice that the sand terrain above is different from the [terrain_type] for an embellishment in two ways. It has a name key as well as an editor_name, and it has no aliasof key.

The name key is the primary name for a [terrain_type]. It will appear while playing, and if no editor_name is provided, it will apppear there as well.

The aliasof key solves the problem of many [terrain_type]s but few ids appearing in the [movetype]. It provides a list of terrains that this terrain is equivalent to by the string key of the terrain. The string keys for the mainline terrains are:
  • deep_water=Wdt (Wo before 1.11.7)
  • shallow_water=Wst (Ww before 1.11.7)
  • reef=Wrt (Wwr in 1.10, as Cr for some time in 1.11)
  • swamp_water=St (Ss before 1.11.7)
  • flat=Gt
  • sand=Dt (Ds before 1.11.7)
  • forest=Ft (^Fp before 1.9.10)
  • hills=Ht (Hh in 1.10 and earlier)
  • mountains=Mt (Mm in 1.10 and earlier)
  • village=Vt (Vit in 1.11.7-1.11.8 Vi before 1.11.7)
  • castle=Ct (Ch before 1.11.7)
  • cave=Ut (Uu before 1.11.7)
  • frozen=At
  • unwalkable=Qt
  • fungus=Uft (^Uf before 1.11.7)
  • impassable=Xt
Overlay terrains (those starting with ^), take priority over base terrains. When they are present, the [terrain_type] of the base is ignored for purposes of movement and defense. The value of the base terrain can be specifically included by adding the special value "_bas" to the aliasof key for the overlay (as we did for the embellishments earlier).

You can include multiple terrain strings in the aliasof list if they are separated by commas. The game will evaluate them from left to right, taking the value from the later one if it is better. Adding a "-" as one of the terrain strings cause the ones that come after it to be chosen if they are worse than the previous value. "_bas" actually inserts the contents of the base terrain into the string, which can cause some unexpected consequences in some situations. To avoid these, try to ensure that "_bas" is always the first terrain named in a list. For instance, villages are defined as "_bas,Vt" in 1.12. If they were defined as "Vt,_bas", and the base happened to be snowy hills "-,At,Hh", then the result would be "Vt,-,At,Hh" producing the worse of At, Hh and Vt. By writing it as "_bas,Vt", the result is "-,At,Hh,+,Vt", which produces the desired village movement whenever it is better than the base.

You can affect movement separately from defense by using mvt_alias and def_alias. Generally, you should always have an aliasof and one of the two keys here, preferring the one that is simpler to read.

Some examples from mainline:

Code: Select all

# Same as flat (Cobbles)
aliasof=Gt

# Better of village and base terrain (every village)
aliasof=_bas, Vt

# Best defense and worst movement from cave and hills (Rockbound Cave)
aliasof=Ut, Ht
mvt_alias=-,Ut, Ht

# Defense as base, move like flat (Mine Rail)
aliasof=_bas
mvt_alias=Gt
You don't have to refer only to the string keys for the basic mainline terrains. For instance, Winter Mixed Forested Hills refers to Snow Hills in its definition because it is easier to understand. The aliases will chain until a base terrain is reached. This terrain definition was removed from mainline during 1.11, the definition is as it appears in 1.8.

Code: Select all

aliasof=Ha,^Fp (same as Hh,At,^Fp)
mvt_alias=-,Ha,^Fp (same as -,Hh,At,^Fp)
Villages
Villages require two extra keys, one for the healing part and one for the income part. This is a typical village definition.

Code: Select all

[terrain_type]
    symbol_image=village/camp-tile
    id=camp_village
    editor_name= _ "Tent Village"
    string=^Vct
    aliasof=_bas, Vt
    default_base=Re
    heals=8
    gives_income=true
    editor_group=village
[/terrain_type]
All villages in mainline have the same values for heals, and gives_income. Except for the merfolk villages, they all have the same aliasof value as well. Make sure these match when defining your own village. (The VILLAGE (1.8) and NEW:VILLAGE (1.9+) macros should be used for the terrain graphics rules. VILLAGE allows the P,L,F and RANDOM parameters, while NEW:VILLAGE has hidden @V text to provide variations.) You can also use these parameters separately for special effects.

Finally, you will notice one extra key: default_base. When this key is specified, the map editor will automatically apply the specified base terrain when placing the terrain on the map unless the user holds down the shift key.

Castles and Keeps
These are very simple. Castles have the recruit_onto key set to true, while Keeps have both recruit_onto and recruit_from set to true. Setting recruit_from without setting recruit_onto is possible, but creates a castle with zero possible tiles to recruit onto since castle connection is determined only by recruit_onto, so the keep will be connected to zero castle tiles and be useless for recruiting.

Light modification
The light key works the same way illuminates does, but since there is no limit for it in 1.10, it stacks with everything. The value here is added to lawful_bonus from [time] to generate the final result.

As of 1.11.1, max_light and min_light provide maximum and minimum limits for the bonus. If not specified, both have a value of 0. A positive value for light can never cause the bonus to decrease from the base time of day and a negative value can never cause the bonus to increase, regardless of the values of the limits.

Special Abilities
Several special abilities (hides, tunnel, leadership) have filters in them. Note that [filter_location] uses the terrain string to match terrains, so your choice of string may affect how these abilities work.
Last edited by Alarantalara on November 6th, 2014, 2:00 am, edited 10 times in total.
Reason: Base terrain string update (1.11.7, 1.11.9)
User avatar
Captain_Wrathbow
Posts: 1664
Joined: June 30th, 2009, 2:03 pm
Location: Guardia

Re: Custom Terrain Tutorial planning

Post by Captain_Wrathbow »

:shock:

:D


You have absolutely no idea how helpful this is. Thank you so much for posting this! I consider myself fairly proficient with most areas of WML, but TerrainWML has been something I've always been afraid to deal with.

This will be an extremely useful resource in coding terrains... I have a feeling I'll be referring to this thread a lot in the future. IMHO, this ought to be a sticky...
User avatar
Alarantalara
Art Contributor
Posts: 786
Joined: April 23rd, 2010, 8:17 pm
Location: Canada

Base Terrains and Transitions

Post by Alarantalara »

Images for earlier terrain examples have all been single, non-tiling images. While this works well for villages, some embellishments and a few other terrain pieces, many terrains cover areas of the map. These terrains consist of a collection of tiles that are the size of one hex and usually one or more sets of transitions.

Single image tiles should be 72x72 pixels and have an alpha mask that matches the shape of the tile (available at data/core/images/terrain/mask.png).

If your image needs to tile properly, I suggest the following tutorials on the wiki: The image for a base terrain should be set using the TERRAIN_BASE macro. As mentioned before, it features the same options (P,L,F,B,RANDOM) as the OVERLAY macro.

Transitions with Other Terrain

For mainline terrains, the TRANSITION_COMPLETE macro is most commonly used, since it means that the programmer does not have to track exactly which terrain tiles have been drawn.

It takes two terrain sets, a exterior terrain, which surrounds a single hex, and an interior terrain, which is represented by a single hex that has the exterior terrain on one or more sides.

The transition images are centered on the interior terrain hex, so most of the time, a 72x72 pixel image showing the transition will cover the needed area.

The image files must be named according to the following rules:
  • All files must share the same base name
  • All files must end in .png
  • The base name must be followed by a list of directions the exterior terrain may be found separated by '-'s. The list of directions must be in clockwise order around the interior hex and they must not skip a direction.
    The directions are: n, ne, se, s, sw, nw
Some example names from core:
green-s.png
dry-nw-n-ne.png
green-s-sw-nw-n-ne-se.png

If a 72x72 image is used for the transitions as suggested, then the directions named are the sides of the hex that the transition should come in from.

Terrain Matching

While choosing the string to match your new terrain (typically the exterior terrain above) is easy, the correct string for the non-matching terrain can be much more complicated.
The simplest form is to just match everything that is not your terrain (!,MyT), however, you will often not want to use your transition for some terrains, like water.

Wesnoth matches terrain strings in the following way. It scans the list of terrains from left to right, trying to match it against the terrain. If the string matches then it stops and reports a successful match. If it encounters a !, it switches to reporting matching terrain as unsuccessful. If it encounters a second !, then it switches back to reporting a match as successful. When it reaches the end of the list, it reports success if it saw an odd number of !s and failure if even. Success means that the [terrain_graphics] rule can apply if all other conditions are met, while failure means it doesn't.

This example from core says match all castles and keeps except three (Chw, Khw, Khs). Since these three are are watery castles, there should be no coast for those three but the drawn cliff should appear for the remaining castles, and that's what this does.

Code: Select all

{TRANSITION_COMPLETE_LF    (!,Chw,Khw,Khs,!,C*,K*)            W*          -510 submerged_part     castle/castle-to-water}
Note that the other side is any Water terrain under the convention that water always starts with a W.

The example also shows the use of * as a wildcard to match any number of letters in the string. Overlay terrains usually require it as the first character to make sure that all base terrains are covered. There is a special exception for base terrains such that if the base terrain matches a terrain with a base and an overlay, it still matches the terrain even if a * is not present. If you need to do something different for that case, then match the other cases first in the list.

Dealing with Problem Transitions
Many of the transitions in mainline may cause problems with your own transitions. They may not appear when you want them to, or they may appear when you don't want them.
The first problem is easily solved: simply add a copy of the missing transition command to your add-on with your terrain added to the list of matching terrains.
The second problem can cause greater difficulties, especially since the transition you have drawn may be missing. While the exact solution may vary depending on the terrain, the following suggestions will usually help.
  • Try making your terrain string correspond to the conventions from TerrainCodesWML. Even though Y and Z for the first string are reserved for UMC, it is generally better to use the standard code for your terrain and include a y or z as a later character to avoid conflicts with mainline. For example, terrains starting with Q will not have the chasm edges drawn against them in transitions with the chasm and lava chasm terrains.
  • You can use the DISABLE_BASE_TRANSITIONS macro, which is basically an image free, more efficient version of TRANSITION_COMPLETE which you can use to turn off many of the transitions. DISABLE_BASE_TRANSITIONS allows you to specify an optional flag which will let you turn off castle, track/bridge, and fence transitions if you should need it. The other optional parameters are irrelevant to an image free macro and are not available. Because mainline terrains use many flags for transitions, the optional flag is often very useful - look at how there is a submerged_part flag in the matching example. If you created your own underwater castle, this macro with that flag set would be required.
  • To disable wall drawing (castles, impassable cave), there is a DISABLE_WALL_TRANSITIONS macro which should be used instead of DISABLE_BASE_TRANSITIONS. It works the same way but covers the flags used by walls (which use different suffixes than the base transitions do).
Layers
Another issue with transitions arises at corners where three different terrains intersect. Given three terrains, A, B, and C, with transitions defined for A->everything and B->everything in that order. Since terrains are drawn in the same order the rules appear, the corner meeting a hex with A, B and C, will have the A transition drawn on top of hexes B and C, then the B transition drawn on hex C. The result is that the B transition will be on top of the A transition, leading to an ugly break in the transition. To avoid this, you should assign every transition a layer, with each transition being on a lower (more negative) layer than the one before it. In this way, the transitions that are chosen first are drawn on top of the later transitions, which achieves the desired appearance. If you examine terrain_graphics.cfg, you will see that the very large transition section follows this rule.

Wesnoth places all mainline graphics rules after any top-level [terrain_graphics] rules you define. This means that an add-on's rules will always be applied and drawn first. Therefore, if you define a transition, make sure that you assign it a layer that is higher than any transitions it will preempt. In 1.9.7 the highest layer used for most transitions is -166, while some terrain features like fences are at layer -80, so the layers between -100 and -150 should work for most transitions in an add-on. Chasm transitions are at layers -80 and -90, but because they do not use the standard transition flags, they will be drawn even if another transition is specified unless they are explicitly skipped. Keeping your transitions below layer -90 will ensure that chasm edges appear on top of your transitions in the three cornered case.
Example using modified terrains without layers. Note that the grass covers the flagstones only near dirt.
Example using modified terrains without layers. Note that the grass covers the flagstones only near dirt.
bad_layering.png (22.67 KiB) Viewed 11955 times
Finally, while layers -100 to -150 are the safest to use for new terrain, especially if combined with a rule that matches most other terrain types, if your terrain has great affinity for another, you should make sure that you pick a layer in the appropriate range in mainline. For instance, if you create a new water terrain that only has transitions with other water terrains, define its layer to be lower than -563 so it appears below all the sand->water transitions. More generally, if you want your transition to not apply to an existing terrain, make sure that the transition that will be used is defined at a higher layer than yours.

Double Sided Transitions
Normally, only one transition image is drawn for a border between two terrain types. By using a second flag and switching the order of the terrains, it is possible to draw a transition from terrain 1 to 2 and then a second from 2 to 1, each occupying 1 hex. If such a transition only occurs with one other terrain, this is not needed, a larger image based around a terrain hex in the center will satisfy the problem. It should be used only when you can reasonably draw several half transitions that match each other. There are few examples of this in mainline, with the grass-grass transitions being the primary example.

TODO for this section: add more images
Last edited by Alarantalara on July 19th, 2015, 3:54 pm, edited 8 times in total.
Reason: Add information about DISABLE_WALL_TRANSITIONS
User avatar
artisticdude
Moderator Emeritus
Posts: 2424
Joined: December 15th, 2009, 12:37 pm
Location: Somewhere in the middle of everything

Re: Custom Terrain Tutorial planning

Post by artisticdude »

Giving my whole-hearted approval to this project. :) Terrain WML has always been something of a mystery to me, and I'd be glad for anything that could help me understand it better.
Alarantalara wrote:If your image needs to tile properly, I suggest the following tutorials on the wiki:
•How to Make Seamless Tiles
•Seamless Tiles Using Inkscape
•Turning Square Tiles into Hex
Another link on creating terrain graphics (one I found very helpful) is messilac's essay on terrain perspective.
"I'm never wrong. One time I thought I was wrong, but I was mistaken."
User avatar
TheBladeRoden
Posts: 168
Joined: July 16th, 2007, 8:01 am

Re: Custom Terrain Tutorial planning

Post by TheBladeRoden »

this thread should be stickied :eng:
Founding Father of Columbia
User avatar
Alarantalara
Art Contributor
Posts: 786
Joined: April 23rd, 2010, 8:17 pm
Location: Canada

The [terrain_graphics] Tag

Post by Alarantalara »

For those who were expecting coverage of the castle wall macros next, I will point out that most of the difficulty in creating them is in drawing tiles that match the rules imposed on how the tiles fit together. Since this tutorial is trying to focus on the code rather than the drawing I will leave it for now.

Structure
The terrain graphics tag is made of two parts: a set of rules that determine what the tag applies to, and a set of image tags that determine what is drawn when the rule matches. The tag requires at least one rule to be useful, but there are no required tags. Therefore, the simplest possible tag is:

Code: Select all

[terrain_graphics]
[/terrain_graphics]
This tag is useless, as it applies to nothing and draws no image.

Rules
The first step in making the tag useful is to define what it applies to through rules. The [tile] tag is the fundamental unit for a rule. As its name suggests, it describes a single tile on the map.

The [tile] tag has another role beyond defining rules. They also represent all of the hexes that an image for the [terrain_graphics] tag can be drawn on. If there is no tile describing the hex in the tag, then nothing may be drawn on it by that tag.

Images
Images will be covered in more detail in a later tutorial. For now, an image is created using the [image] tag with the key name to specify the file name relative to images/terrain. The image tag may appear inside a tile rule, in which case it will be drawn in that hex only, or it may appear directly within the [terrain_graphics] tag, in which case it will be drawn over all hexes identified with [tile] tags, limited only by the size of the image.

With such syntax, the image will be drawn so that its top-left corner is in the top-left corner of the rectangle containing the hexes for drawing. (This isn't exactly correct, but it's close enough to be useful.)

Code: Select all

[terrain_graphics]
    [tile]
        [image]
            name=myterrainimage.png # image in tile
        [/image]
    [/tile]
    [image]
        name=myotherterrainimage.png # image applied to all tiles
    [/image]
[/terrain_graphics]
In 1.8 the .png extension must be left off, in 1.9 it must be included. This is different from the macros described earlier, as they all add the .png extension for you in 1.9.

Coordinate System
The first part of a [tile] rule is the identification of which tile on the game map is being checked by the rule. The map in Wesnoth has coordinates for each tile, running from <0,0> in the top left to <width,height> in the bottom right. These coordinates are the global coordinates of a map tile. The coordinates of every tile on the map can also be described relative to another tile. The relative coordinates reflect the results you would get if you placed the Wesnoth map grid so that the reference tile is located at <0,0>. This is not necessarily the same result as what you would get if you simply subtracted one global coordinate from another. The result will be the same if the reference tile was originally at an even coordinate, but the relative y-coordinate of the other tile may be different by 1 if the reference tile was originally at an even coordinate. To see why this change in y-coordinates is needed, open any map and resize it by removing the leftmost column of the map. If the y-coordinate were not adjusted, the same distortion would occur when applying map rules.

All [tile] locations are specified using the relative coordinate system. The standard x and y keys are used to specify the coordinates. Both the x and y keys must be specified. For every hex on the map, the game engine will make it the <0,0> hex in relative coordinates, then try to evaluate each rule from that perspective.

The structure of a tag that applies to every hex on the map is thus:

Code: Select all

[terrain_graphics]
    [tile]
        x=0
        y=0
    [/tile]
[/terrain_graphics]
If you also wanted to affect the tile two tiles below every tile with the rule, then a second [tile] tag produces the required result:

Code: Select all

[terrain_graphics]
    [tile]
        x=0
        y=0
    [/tile]
    [tile]
        x=0
        y=2
    [/tile]
[/terrain_graphics]
You can limit the list of locations used as anchor points for the rest of the rules to exactly one by including x and y keys within the [terrain_graphics] tag directly. If this is done, then the x and y coordinates will all be relative to the location specified. The location must be on the map. This means that x and y must be at least 1 and at most the width and height of the map.

The following code will look at only the hexes at <4,5> and <5,7>

Code: Select all

[terrain_graphics]
    x=4
    y=5
    [tile]
        x=0
        y=0
    [/tile]
    [tile]
        x=1
        y=2
    [/tile]
[/terrain_graphics]
Terrain Restrictions
If only coordinates are specified, the tile always matches the hex at the relative location. Since it is very unlikely that an image should be drawn on every map hex, there are several restrictions that may be added to the [tile]s to make them not match everything. The first is a terrain type.
All it requires is a type key added to the tile. It uses the same terrain string format described earlier.
This example matches all green grass tiles on the map that are immediately above shallow water.

Code: Select all

[terrain_graphics]
    [tile]
        x=0
        y=0
        type=Gg # match green grass
    [/tile]
    [tile]
        x=0
        y=1
        type=Ww # match shallow water
    [/tile]
[/terrain_graphics]
The probability from the macros is the key probability and it works the same way as it did for the macros. It appears outside of the [tile] tags as it applies to the entire rule.

Code: Select all

[terrain_graphics]
    [tile]
        x=0
        y=0
    [/tile]
    probability=70 # rule only applies 70% of the time
[/terrain_graphics]
Flags
Flags were mentioned in the macros, but unlike the other restrictions, they are much more versatile in the actual tag. There are three keys in 1.8, plus an extra one in 1.9 to cover the most common case. They are:
  • has_flag: rule applies if the flag has been set by an earlier rule on the hex
  • no_flag: rule applies if the flag has not been set by an earlier rule on the hex
  • set_flag: set the flag for use by later rules
  • set_no_flag: a combination of no_flag and set_flag (requires 1.9)
All of these keys take a comma separated list of flags.

Here is a slightly modified example taken from the campaign Roar of the Woses. It uses a rule that draws no image to turn off waterfalls underneath chasm bridges, but allows multiple waterfalls to be drawn if they fit on that hex border. It provides an example of why you might use set_flag and no_flag in different rules rather than the same one.

Code: Select all

# disable under bridges
[terrain_graphics]
    [tile]
        x=0
        y=0
        type=Qxu^Bs\
        set_flag=waterfall-nw,waterfall-se
    [/tile]
[/terrain_graphics]

#two of the waterfalls
[terrain_graphics]
    [tile]
        x=0
        y=0
    [/tile]
    [tile]
        x=0
        y=1
        type=Wwy,Woy
    [/tile]
    [tile]
        x=1
        y=0
        type=Q*
    [/tile]
    [tile]
        x=1
        y=1
        type=Qxu
        no_flag=waterfall-nw
    [/tile]
    [tile]
        x=0
        y=2
        type=Q*
    [/tile]
    [image]
        name=water/waterfall-nw-n-sw.png
    [/image]
[/terrain_graphics]
[terrain_graphics]
    [tile]
        x=0
        y=0
        type=Wwy,Woy
    [/tile]
    [tile]
        x=1
        y=0
        type=Qxu
        no_flag=waterfall-nw
    [/tile]
    [tile]
        x=0
        y=1
        type=!,Q*
    [/tile]
    [image]
        name=water/waterfall-cw-nw.png
    [/image]
[/terrain_graphics]
The next part will explore [image] in detail, including image path functions, the complete layering system, and variant images. However, since I have observed some interesting anomalies in how images are layered, it may take some time before I can write a complete explanation.
Last edited by Alarantalara on January 8th, 2012, 5:13 pm, edited 2 times in total.
Reason: Removed dead link
User avatar
Iris
Site Administrator
Posts: 6797
Joined: November 14th, 2006, 5:54 pm
Location: Chile
Contact:

Re: Custom Terrain Tutorial planning

Post by Iris »

Thanks a lot for taking the time to figure out this mess. I’ll definitely come back here the next time I find myself fiddling around with new terrains.

A little historical observation, though…
Alarantalara wrote:Ayin has written a tutorial (also linked in the wiki) for the terrain_graphics tag. While it was written for 1.4, the tag has not changed a lot and still provides a very good overview.
Judging by its use of single-letter terrain strings (multi-letter strings appeared in 1.3.x after mordante’s branch was merged in trunk), and that Ayin’s forum account was last used the day before the 1.0.2 release was tagged, it must have been written for 1.0 and earlier rather than 1.4.
Author of the unofficial UtBS sequels Invasion from the Unknown and After the Storm.
Post Reply