Difference between revisions of "ConventionsWML"

From The Battle for Wesnoth Wiki
m (automated change of forum links)
(Update links to macro-reference.html)
 
(16 intermediate revisions by 7 users not shown)
Line 1: Line 1:
 
The purpose of this page is to list conventions of WML --
 
The purpose of this page is to list conventions of WML --
 
that is, things that make WML more readable and flexible.
 
that is, things that make WML more readable and flexible.
Note that this page is not official;
+
 
in fact most mainline campaigns do not follow this.
+
== Use wmlscope, wmllint, and wmlindent ==
 +
 
 +
The WML [[Maintenance_tools|maintenance tools]] will help you ensure that your WML is clean, up-to-date, and correct.  Use them early and often; they will save you a lot of trouble later by catching entire classes of WML bugs before a user can ever see them.
  
 
== Macros ==
 
== Macros ==
  
 
Using macros is useful for decreasing the size of a file,
 
Using macros is useful for decreasing the size of a file,
and for making it clear
+
and for making it clear that you are doing the same thing several times.
that you are doing the same thing several times.
+
It is economical to use '''[https://www.wesnoth.org/macro-reference.html macros from the standard library]''' rather than writing your own whenever you can, but don't hesitate to write your own when the standard library does not do what you need.
A good rule for when to use macros
 
is to use them whenever information is being repeated.
 
For information on how to create and use macros, see [[PreprocessorRef]].
 
  
Also, if you are writing a campaign,
+
A good rule for when to write a macro is to use them whenever information or code is being duplicated and all the duplications might have to be changed in the same way later. For information on how to create and use macros, see [[PreprocessorRef]].
you should use campaign macros.
 
These are macros in the main .cfg file of your campaign;
 
i.e. the one with the [campaign] tag.
 
They can be used in any scenario of your campaign.
 
One useful campaign macro is a "deaths" macro, which describes events
 
that should occur in all scenarios of your campaign;
 
for example an event causing you to lose when your hero dies.
 
Refer to this macro in each of your scenarios.
 
  
Put campaign macros after the #ifdef of your campaign;
+
Conventionally, your macro definitions should live in one or more files within a directory called utils under your main campaign directory.  Be sure to
that way they will not conflict with other campaign's macros.
+
include that directory in your _main.cfg.
  
 
== Indentation ==
 
== Indentation ==
  
In indentation, every subtag is indented 1 level outward of its parent tag.
+
We used to have complicated recommendations for indentation. Now we have a WML indenting program and much simpler rules.
Toplevel tags are not indented;
 
neither are the direct subtags of macros and files.
 
For example, in unit files [unit] is not indented,
 
and every macro should have at least 1 unindented tag or attribute.
 
A macro references should be indented
 
as though it were the contents of the macro it refers to.
 
Some macros require the use of another macro later;
 
in this case the macro should be considered as a tag,
 
with its counterpart as the closing tag.
 
 
 
Example:
 
 
 
[scenario]
 
  [event]
 
#define START_STORE_UNIT
 
[store_unit]
 
  [unit]
 
#enddef
 
#define END_STORE_UNIT
 
  [/unit]
 
variable=temp
 
[/store_unit]
 
#enddef
 
  {START_STORE_UNIT}
 
  type=Elvish Fighter
 
    [not]
 
    x,y=$x1,$y1
 
    [/not]
 
  {END_STORE_UNIT}
 
  [/event]
 
[/scenario]
 
 
 
Although spaces can substitute for tabs (as done in this wiki),
 
it is generally not advisable to use a series of spaces
 
to substitute for a single tab - one is enough.
 
 
 
Some writers don't indent subtags of [if]
 
because of the way these tags are used recursively;
 
indenting these tags fully could cause line wraps
 
to make the code incomprehensible.
 
  
There are two ways to indent keys:
+
Be aware that no matter how you indent your WML, if it's accepted into mainline we are going to run <tt>wmlindent</tt> on it and smash it into the house style. We do this so our WML maintainers won't have to cope with lots of idiosyncratic indentation variants. You can make your WML more readable by writing in the house style to begin with.
normal indentation, and savefile indentation.
 
In normal indentation, a key is indented
 
on the same level as the tag containing it,
 
and in savefile indentation a key is indented
 
1 level outward of that.
 
  
Examples:
+
# Indent each level with '''4 spaces'''.
 +
# Indent attributes a level deeper than their parent tag.
 +
# Indent macros as though the <tt>#define/#enddef</tt> are an outermost level; that is, the macro body starts with one level of indenting. Same applies to <tt>#undef</tt>.
 +
# Don't indent <tt>#ifdef</tt>/<tt>#ifndef</tt>/<tt>#else</tt>/<tt>#endif</tt> at all
 +
# Indent comments at the same level as the text they go with.
  
Normal indentation:
+
When in doubt, run <tt>wmlindent</tt> on your code. See [[Maintenance tools]] for more description of this program.
  [scenario]
 
turns=16
 
  [side]
 
  side=1
 
  [/side]
 
[/scenario]
 
  
Savefile indenatation:
+
:'''Note:''' Although 4 spaces is the mainline style, there's absolutely ''nothing'' wrong with tabs either. Those of you who prefer a simpler Notepad program should not feel compelled to use spacebar and/or delete key four times the necessary amount when you can simply use tabs. In any case, it is very easy to convert these to the standard convention using <tt>wmlindent</tt>, so don't be scared to use your preferred method of indentation when working with WML. The most important thing to keep in mind is that your code should be uniformly indented, nested to the proper level, and using a form of whitespace that is easy for you to read, work with, and debug.
[scenario]
 
  turns=16
 
  [side]
 
  side=1
 
  [/side]
 
[/scenario]
 
 
 
It doesn't matter what indentation format you use,
 
but if a file is not indented
 
then it is harder to tell what is going on;
 
for example it is difficult to catch errors in tag matchups.
 
  
 
== Naming files ==
 
== Naming files ==
Line 110: Line 43:
 
That way it is easier to tell which scenario is next.
 
That way it is easier to tell which scenario is next.
  
If files are named in a numerical order,
+
On some systems, filenames are case-sensitive. This means that if the ID has capital or lowercase letters, then the files must have identical capital or lowercase letters.
put 0 at the beginning of single-digit numbers.
+
 
This makes the alphabetical sorting also a numerical sorting.
+
Use the scenario number and an underscore as a name prefix of your scenario files, and if you have more than 9 of these put 0 at the beginning of single-digit numbers. This will make them list in order, which is convenient for people trying to read your campaign.
For example if you have 20 different maps, you can name them
+
 
'MAP_01', 'MAP_02'...., 'MAP_20'.
+
While many campaigns use the same sort of number prefixing for their map files, it's better not to if (as sometimes happens) your campaign needs to use the same map twice.
  
 
== WML variables ==
 
== WML variables ==
Line 124: Line 57:
 
clear meaningless variables using [clear_variable].
 
clear meaningless variables using [clear_variable].
  
For variable values, use 'yes' and 'no' for boolean values
+
For variable values, use 'yes' and 'no' for boolean values. (Wesnoth does not accept 1 or 0 as boolean values; see [[ConditionalActionsWML#Boolean Values]].
rather than 1 and 0.
 
It's clearer to people who don't know programming.
 
  
 
== See Also ==
 
== See Also ==
 
* [[ReferenceWML]]
 
* [[ReferenceWML]]
 +
 +
[[Category:WML Reference]]

Latest revision as of 08:16, 24 August 2021

The purpose of this page is to list conventions of WML -- that is, things that make WML more readable and flexible.

Use wmlscope, wmllint, and wmlindent

The WML maintenance tools will help you ensure that your WML is clean, up-to-date, and correct. Use them early and often; they will save you a lot of trouble later by catching entire classes of WML bugs before a user can ever see them.

Macros

Using macros is useful for decreasing the size of a file, and for making it clear that you are doing the same thing several times. It is economical to use macros from the standard library rather than writing your own whenever you can, but don't hesitate to write your own when the standard library does not do what you need.

A good rule for when to write a macro is to use them whenever information or code is being duplicated and all the duplications might have to be changed in the same way later. For information on how to create and use macros, see PreprocessorRef.

Conventionally, your macro definitions should live in one or more files within a directory called utils under your main campaign directory. Be sure to include that directory in your _main.cfg.

Indentation

We used to have complicated recommendations for indentation. Now we have a WML indenting program and much simpler rules.

Be aware that no matter how you indent your WML, if it's accepted into mainline we are going to run wmlindent on it and smash it into the house style. We do this so our WML maintainers won't have to cope with lots of idiosyncratic indentation variants. You can make your WML more readable by writing in the house style to begin with.

  1. Indent each level with 4 spaces.
  2. Indent attributes a level deeper than their parent tag.
  3. Indent macros as though the #define/#enddef are an outermost level; that is, the macro body starts with one level of indenting. Same applies to #undef.
  4. Don't indent #ifdef/#ifndef/#else/#endif at all
  5. Indent comments at the same level as the text they go with.

When in doubt, run wmlindent on your code. See Maintenance tools for more description of this program.

Note: Although 4 spaces is the mainline style, there's absolutely nothing wrong with tabs either. Those of you who prefer a simpler Notepad program should not feel compelled to use spacebar and/or delete key four times the necessary amount when you can simply use tabs. In any case, it is very easy to convert these to the standard convention using wmlindent, so don't be scared to use your preferred method of indentation when working with WML. The most important thing to keep in mind is that your code should be uniformly indented, nested to the proper level, and using a form of whitespace that is easy for you to read, work with, and debug.

Naming files

First of all, don't put spaces in filenames; this causes errors on some systems. Use underscores(_) instead.

If the IDs of your scenarios are different from their names, name the files after the IDs, not the names. That way it is easier to tell which scenario is next.

On some systems, filenames are case-sensitive. This means that if the ID has capital or lowercase letters, then the files must have identical capital or lowercase letters.

Use the scenario number and an underscore as a name prefix of your scenario files, and if you have more than 9 of these put 0 at the beginning of single-digit numbers. This will make them list in order, which is convenient for people trying to read your campaign.

While many campaigns use the same sort of number prefixing for their map files, it's better not to if (as sometimes happens) your campaign needs to use the same map twice.

WML variables

(For information about what WML variables are, see VariablesWML.) These shouldn't be used except when necessary. [have_unit] tags can often be used instead. Also, make sure that your scenarios clear meaningless variables using [clear_variable].

For variable values, use 'yes' and 'no' for boolean values. (Wesnoth does not accept 1 or 0 as boolean values; see ConditionalActionsWML#Boolean Values.

See Also

This page was last edited on 24 August 2021, at 08:16.