<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-GB">
	<id>https://www.tt-wiki.net/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Yexo</id>
	<title>TTWiki - User contributions [en-gb]</title>
	<link rel="self" type="application/atom+xml" href="https://www.tt-wiki.net/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Yexo"/>
	<link rel="alternate" type="text/html" href="https://www.tt-wiki.net/wiki/Special:Contributions/Yexo"/>
	<updated>2026-05-02T02:17:05Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.8</generator>
	<entry>
		<id>https://www.tt-wiki.net/index.php?title=NMLTutorial/Train_three_part_articulated&amp;diff=7985</id>
		<title>NMLTutorial/Train three part articulated</title>
		<link rel="alternate" type="text/html" href="https://www.tt-wiki.net/index.php?title=NMLTutorial/Train_three_part_articulated&amp;diff=7985"/>
		<updated>2011-12-13T22:33:04Z</updated>

		<summary type="html">&lt;p&gt;Yexo: /* Start/stop callback */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{NMLTutorial}}&lt;br /&gt;
&#039;&#039;The example used here is from the [http://dev.openttdcoop.org/projects/nml/repository/show/examples NML source]. The code for this was originally written in NFO by DJNekkid for the 2cc Trainset and rewritten in NML by Hirundo. The graphics used in the example are by Purno. Code and graphics are both licensed according to the GPL v2 or later. The code has been modified for the purpose of this tutorial&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This continues the [[NMLTutorial/Train single engine|second part]] of the train example. The train will be made into an articulated EMU that can be purchased all at once.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Callbacks ==&lt;br /&gt;
Except the articulated vehicle callback, we&#039;ll add two more callbacks to only allow attaching more of these multiple units (and not other trains/wagons) and to give the train a maximum length.&lt;br /&gt;
&lt;br /&gt;
The callbacks and switch blocks that are needed for this will be discussed below. What callbacks are available for vehicles can be found in the [http://newgrf-specs.tt-wiki.net/wiki/NML:Vehicles#Vehicle_callbacks NML Documentation]. From here you can decide what callbacks suit your needs and find their names to be used in the graphics block.&lt;br /&gt;
&lt;br /&gt;
=== Articulated part callback ===&lt;br /&gt;
We have seen this one before in the tram example. Returning a single value is not enough for this callback, so we need to reference a switch block to handle the callback.&lt;br /&gt;
&lt;br /&gt;
Add to the graphics block:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
        articulated_part:             sw_icm_articulated_part;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The callback needs to return the identifier of a vehicle for as long as you want to keep adding parts and return &amp;lt;code&amp;gt;CB_RESULT_NO_MORE_ARTICULATED_PARTS&amp;lt;/code&amp;gt; to stop the process. During the callback the game will continuously call the callback, each time increasing the &amp;lt;code&amp;gt;extra_callback_info1&amp;lt;/code&amp;gt; [http://newgrf-specs.tt-wiki.net/wiki/NML:General variable] by one.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_articulated_part, extra_callback_info1) {&lt;br /&gt;
    /* Add two articulated parts, for a total of three */&lt;br /&gt;
    1 .. 2: return item_icm;&lt;br /&gt;
    return CB_RESULT_NO_MORE_ARTICULATED_PARTS;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This causes the callback to be called three times, adding two extra parts to the &amp;lt;code&amp;gt;item_icm&amp;lt;/code&amp;gt; vehicle. For an extended explanation of this, see the tram example.&lt;br /&gt;
&lt;br /&gt;
=== Start/stop callback ===&lt;br /&gt;
The start/stop callback is called whenever a vehicle is started in the depot and decides if the vehicle may leave the depot. The callback must return &amp;lt;code&amp;gt;CB_RESULT_NO_TEXT&amp;lt;/code&amp;gt; to allow the vehicle to leave the depot. If you want to prevent the vehicle from leaving the depot, the callback must return a string containing an error message.&lt;br /&gt;
&lt;br /&gt;
We want to use this callback to check the vehicle length. As such it makes sense to base the decision on the length of the train, which can be found using the &amp;lt;code&amp;gt;num_vehs_in_consist&amp;lt;/code&amp;gt; [http://newgrf-specs.tt-wiki.net/wiki/NML:Vehicles#Vehicle_variables variable]. Because we need to base a decision on some variable, we&#039;ll use a switch block to do that.&lt;br /&gt;
&lt;br /&gt;
Add to the graphics block:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
        start_stop:                   sw_icm_start_stop;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We want to limit our train length to a maximum of four coupled EMUs. As each EMU has a length of three, the total possible train length is twelve. So for train lengths 1 to 12 we want to return &amp;lt;code&amp;gt;CB_RESULT_NO_TEXT&amp;lt;/code&amp;gt; (and allow the train to leave the depot). For any other train length we return a string to disallow starting the train and informing the user why that is.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_start_stop, num_vehs_in_consist) {&lt;br /&gt;
    /* Vehicles may be coupled to a maximum of 4 units (12 cars) */&lt;br /&gt;
    1 .. 12: return CB_RESULT_NO_TEXT;&lt;br /&gt;
    return string(STR_ICM_CANNOT_START);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As we added a new string, define it in the language file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
STR_ICM_CANNOT_START         :... train too long (max. 4 coupled EMUs).&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Wagon attach callback ===&lt;br /&gt;
We only want to allow attaching more of the same EMUs to this train. Amongst others, the callback can return a custom string to disallow or return &amp;lt;code&amp;gt;CB_RESULT_ATTACH_ALLOW&amp;lt;/code&amp;gt; to allow attaching. The decision must be made on the basis of the identifier of the wagon that is being attached. We can use the &amp;lt;code&amp;gt;vehicle_type_id&amp;lt;/code&amp;gt; [http://newgrf-specs.tt-wiki.net/wiki/NML:Vehicles#Vehicle_variables variable] to make that decision, using a switch block.&lt;br /&gt;
&lt;br /&gt;
Add to the graphics block:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
        can_attach_wagon:             sw_icm_can_attach_wagon;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will be the switch block:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_can_attach_wagon, vehicle_type_id) {&lt;br /&gt;
    /* SELF refers to the wagon here, check that it&#039;s an ICM */&lt;br /&gt;
    item_icm: return CB_RESULT_ATTACH_ALLOW;&lt;br /&gt;
    return string(STR_ICM_CANNOT_ATTACH_OTHER);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the attached wagon is of the type &#039;&#039;item_icm&#039;&#039;, it is allowed. Otherwise, a custom error message is displayed. This obviously means that we have to add this message to the language file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
STR_ICM_CANNOT_ATTACH_OTHER  :... only other ICMs can be attached to ICM.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Graphics ==&lt;br /&gt;
The final step in making this work is adding the graphics for the second and third part of the train. This is the same as in the tram example: point to a switch from the graphics block, make a decision based on the &amp;lt;code&amp;gt;position_in_consist&amp;lt;/code&amp;gt; [http://newgrf-specs.tt-wiki.net/wiki/NML:Vehicles#Vehicle_variables variable] and point to the spritesets from there.&lt;br /&gt;
&lt;br /&gt;
We already have the graphics and spritesets defined, so that&#039;s no problem.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
/* Choose between front, middle and back parts */&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_graphics, position_in_consist % 3) {&lt;br /&gt;
    0:      set_icm_front_lighted;&lt;br /&gt;
    2:      set_icm_rear_lighted;&lt;br /&gt;
    set_icm_middle;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This particular switch block actually first does a calculation on the &amp;lt;code&amp;gt;position_in_consist&amp;lt;/code&amp;gt; variable before making a decision on the result of that calculation. Here the modulo 3 of the value of &amp;lt;code&amp;gt;position_in_consist&amp;lt;/code&amp;gt; is calculated (&amp;lt;code&amp;gt;%&amp;lt;/code&amp;gt; is the modulo operator, see [http://en.wikipedia.org/wiki/Modulo_operation Wikipedia] for more details on modulo but basically it&#039;s the remainder after devision (by three in this case)).&lt;br /&gt;
&lt;br /&gt;
So for the first three vehicle parts the expression will yield 0, 1 and 2. For part four through six, it will again yield 0, 1 and 2, etc. The callback decision is then made on these three values alone: for part 0 use graphics for the train front, for part 2 use graphics for the train end and for all other parts use graphics for the middle.&lt;br /&gt;
&lt;br /&gt;
Also don&#039;t forget to reference this switch instead of the spriteset directly from the graphics block:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
        default:                      sw_icm_graphics;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Purchase menu sprite ==&lt;br /&gt;
The spriteset for the purchase menu sprite is already there. We only need to reference it from the graphics block&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
        purchase:                     set_icm_purchase;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Total code so far ==&lt;br /&gt;
When put in the correct order, this should now encode as a working NewGRF. The total code so far:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap; max-height: 200px; overflow:scroll&amp;quot;&amp;gt;&lt;br /&gt;
/* Define grf */&lt;br /&gt;
grf {&lt;br /&gt;
    grfid: &amp;quot;NML\00&amp;quot;;&lt;br /&gt;
    /* GRF name and description strings are defined in the lang files */&lt;br /&gt;
    name: string(STR_GRF_NAME);&lt;br /&gt;
    desc: string(STR_GRF_DESC);&lt;br /&gt;
    /* This is the first version, start numbering at 0. */&lt;br /&gt;
    version: 0;&lt;br /&gt;
    min_compatible_version: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Define a rail type table,&lt;br /&gt;
 * this allows referring to railtypes&lt;br /&gt;
 * irrespective of the grfs loaded.&lt;br /&gt;
 */&lt;br /&gt;
railtypetable {&lt;br /&gt;
    RAIL, ELRL, MONO, MGLV,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Basic template for 4 vehicle views */&lt;br /&gt;
template tmpl_vehicle_basic(x, y) {&lt;br /&gt;
    // arguments x, y: coordinates of top-left corner of first sprite&lt;br /&gt;
    [x,      y,  8, 24,  -3, -12] //xpos ypos xsize ysize xrel yrel&lt;br /&gt;
    [x +  9, y, 22, 20, -14, -12]&lt;br /&gt;
    [x + 32, y, 32, 16, -16, -12]&lt;br /&gt;
    [x + 65, y, 22, 20,  -6, -12]&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Template for a vehicle with only 4 views (symmetric) */&lt;br /&gt;
template tmpl_vehicle_4_views(num) {&lt;br /&gt;
    // argument num: Index in the graphics file, assuming vertical ordering of vehicles&lt;br /&gt;
    tmpl_vehicle_basic(1, 1 + 32 * num)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Template for a vehicle with 8 views (non-symmetric) */&lt;br /&gt;
template tmpl_vehicle_8_views(num, reversed) {&lt;br /&gt;
    // argument num: Index in the graphics file, assuming vertical ordering of vehicles&lt;br /&gt;
    // argument reversed: Reverse visible orientation of vehicle, if set to 1&lt;br /&gt;
    tmpl_vehicle_basic(reversed ? 89 : 1, 1 + 32 * num)&lt;br /&gt;
    tmpl_vehicle_basic(reversed ? 1 : 89, 1 + 32 * num)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Template for a single vehicle sprite */&lt;br /&gt;
template tmpl_vehicle_single(num, xsize, ysize, xoff, yoff) {&lt;br /&gt;
    [1, 1 + 32 * num, xsize, ysize, xoff, yoff]&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Define the spritesets, these allow referring to these sprites later on */&lt;br /&gt;
spriteset (set_icm_front_lighted, &amp;quot;gfx/icm.png&amp;quot;) { tmpl_vehicle_8_views(0, 0) }&lt;br /&gt;
spriteset (set_icm_rear_lighted,  &amp;quot;gfx/icm.png&amp;quot;) { tmpl_vehicle_8_views(1, 1) }&lt;br /&gt;
spriteset (set_icm_front,         &amp;quot;gfx/icm.png&amp;quot;) { tmpl_vehicle_8_views(2, 0) }&lt;br /&gt;
spriteset (set_icm_rear,          &amp;quot;gfx/icm.png&amp;quot;) { tmpl_vehicle_8_views(3, 1) }&lt;br /&gt;
spriteset (set_icm_middle,        &amp;quot;gfx/icm.png&amp;quot;) { tmpl_vehicle_4_views(4)    }&lt;br /&gt;
spriteset (set_icm_purchase,      &amp;quot;gfx/icm.png&amp;quot;) { tmpl_vehicle_single(5, 53, 14, -25, -10) }&lt;br /&gt;
spriteset (set_icm_invisible,     &amp;quot;gfx/icm.png&amp;quot;) { tmpl_vehicle_single(6,  1,  1,   0,   0) }&lt;br /&gt;
&lt;br /&gt;
/* Choose between front, middle and back parts */&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_graphics, position_in_consist % 3) {&lt;br /&gt;
    0:      set_icm_front_lighted;&lt;br /&gt;
    2:      set_icm_rear_lighted;&lt;br /&gt;
    set_icm_middle;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* --- Articulated part callback  --- */&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_articulated_part, extra_callback_info1) {&lt;br /&gt;
    /* Add three articulated parts, for a total of four */&lt;br /&gt;
    1 .. 2: return item_icm;&lt;br /&gt;
    return CB_RESULT_NO_MORE_ARTICULATED_PARTS;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* --- Start/stop callback  --- */&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_start_stop, num_vehs_in_consist) {&lt;br /&gt;
    /* Vehicles may be coupled to a maximum of 4 units (12 cars) */&lt;br /&gt;
    1 .. 12: return CB_RESULT_NO_TEXT;&lt;br /&gt;
    return string(STR_ICM_CANNOT_START);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* --- Wagon attach callback  --- */&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_can_attach_wagon, vehicle_type_id) {&lt;br /&gt;
    /* SELF refers to the wagon here, check that it&#039;s an ICM */&lt;br /&gt;
    item_icm: return CB_RESULT_ATTACH_ALLOW;&lt;br /&gt;
    return string(STR_ICM_CANNOT_ATTACH_OTHER);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Define the actual train */&lt;br /&gt;
item(FEAT_TRAINS, item_icm) {&lt;br /&gt;
    /* Define properties first, make sure to set all of them */&lt;br /&gt;
    property {&lt;br /&gt;
        name:                         string(STR_ICM_NAME);&lt;br /&gt;
        // not available in toyland:&lt;br /&gt;
        climates_available:           bitmask(CLIMATE_TEMPERATE, CLIMATE_ARCTIC, CLIMATE_TROPICAL); &lt;br /&gt;
        introduction_date:            date(1983, 1, 1);&lt;br /&gt;
        model_life:                   VEHICLE_NEVER_EXPIRES;&lt;br /&gt;
        vehicle_life:                 30;&lt;br /&gt;
        reliability_decay:            20;&lt;br /&gt;
        refittable_cargo_classes:     bitmask(CC_PASSENGERS);&lt;br /&gt;
        non_refittable_cargo_classes: bitmask();&lt;br /&gt;
        // refitting is done via cargo classes only, no cargoes need explicit enabling/disabling:&lt;br /&gt;
        refittable_cargo_types:       bitmask(); &lt;br /&gt;
        // It&#039;s an intercity train, loading is relatively slow:&lt;br /&gt;
        loading_speed:                6; &lt;br /&gt;
        cost_factor:                  45;&lt;br /&gt;
        running_cost_factor:          100; // Changed by callback&lt;br /&gt;
        sprite_id:                    SPRITE_ID_NEW_TRAIN;&lt;br /&gt;
        speed:                        141 km/h; // actually 140, but there are rounding errors&lt;br /&gt;
        misc_flags:                   bitmask(TRAIN_FLAG_2CC, TRAIN_FLAG_MU);&lt;br /&gt;
        refit_cost:                   0; //refit costs don&#039;t apply to subcargo display &lt;br /&gt;
        // callback flags are not set manually&lt;br /&gt;
        track_type:                   ELRL; // from rail type table&lt;br /&gt;
        ai_special_flag:              AI_FLAG_PASSENGER;&lt;br /&gt;
        power:                        1260 kW; // Changed by CB&lt;br /&gt;
        running_cost_base:            RUNNING_COST_ELECTRIC;&lt;br /&gt;
        dual_headed:                  0;&lt;br /&gt;
        cargo_capacity:               36; // per part, changed by callback&lt;br /&gt;
        weight:                       144 ton; // Total, changed by callback&lt;br /&gt;
        ai_engine_rank:               0; // not intended to be used by the ai&lt;br /&gt;
        engine_class:                 ENGINE_CLASS_ELECTRIC;&lt;br /&gt;
        extra_power_per_wagon:        0 kW;&lt;br /&gt;
        // 4/12 of weight on driving wheels, with a default friction coefficient of 0.3:&lt;br /&gt;
        tractive_effort_coefficient:  0.3 / 3; // changed by callback&lt;br /&gt;
        air_drag_coefficient:         0.06;&lt;br /&gt;
        shorten_vehicle:              SHORTEN_TO_8_8;&lt;br /&gt;
        // Overridden by callback to disable for non-powered wagons:&lt;br /&gt;
        visual_effect_and_powered:    visual_effect_and_powered(VISUAL_EFFECT_ELECTRIC, 2, DISABLE_WAGON_POWER);&lt;br /&gt;
        extra_weight_per_wagon:       0 ton;&lt;br /&gt;
        bitmask_vehicle_info:         0;&lt;br /&gt;
    }&lt;br /&gt;
    /* Define graphics and callbacks&lt;br /&gt;
     * Setting all callbacks is not needed, only define what is used */&lt;br /&gt;
    graphics {&lt;br /&gt;
        default:                      sw_icm_graphics;&lt;br /&gt;
        purchase:                     set_icm_purchase;&lt;br /&gt;
        start_stop:                   sw_icm_start_stop;&lt;br /&gt;
        articulated_part:             sw_icm_articulated_part;&lt;br /&gt;
        can_attach_wagon:             sw_icm_can_attach_wagon;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Language file so far ===&lt;br /&gt;
english.lng now contains this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap; max-height: 200px; overflow:scroll&amp;quot;&amp;gt;&lt;br /&gt;
##grflangid 0x01&lt;br /&gt;
&lt;br /&gt;
STR_GRF_NAME                 :NML Example NewGRF: Train&lt;br /&gt;
STR_GRF_DESC                 :{ORANGE}NML Example NewGRF: Train{}{BLACK}This NewGRF is intended to provide a coding example for the high-level NewGRF-coding language NML.{}Original graphics by {SILVER}Purno, {BLACK}coding by {SILVER}DJNekkid.{}{BLACK}This NewGRF defines a Dutch EMU, the ICM &#039;Koploper&#039;.&lt;br /&gt;
&lt;br /&gt;
STR_ICM_NAME                 :ICM &#039;Koploper&#039; (Electric)&lt;br /&gt;
STR_ICM_CANNOT_START         :... train too long (max. 4 coupled EMUs).&lt;br /&gt;
STR_ICM_CANNOT_ATTACH_OTHER  :... only other ICMs can be attached to ICM.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This is now a working 3-part EMU. In real life, the EMU is also available as a 4-part variant. In the next part of the tutorial, we will add the option to choose between a 3- and 4 part EMU via a refit.&lt;br /&gt;
&lt;br /&gt;
{{NMLTutorialNavbar|Train single engine|Train four part refit}}&lt;/div&gt;</summary>
		<author><name>Yexo</name></author>
	</entry>
	<entry>
		<id>https://www.tt-wiki.net/index.php?title=NMLTutorial/Train_four_part_refit&amp;diff=7984</id>
		<title>NMLTutorial/Train four part refit</title>
		<link rel="alternate" type="text/html" href="https://www.tt-wiki.net/index.php?title=NMLTutorial/Train_four_part_refit&amp;diff=7984"/>
		<updated>2011-12-13T22:32:42Z</updated>

		<summary type="html">&lt;p&gt;Yexo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{NMLTutorial}}&lt;br /&gt;
&#039;&#039;The example used here is from the [http://dev.openttdcoop.org/projects/nml/repository/show/examples NML source]. The code for this was originally written in NFO by DJNekkid for the 2cc Trainset and rewritten in NML by Hirundo. The graphics used in the example are by Purno. Code and graphics are both licensed according to the GPL v2 or later. The code has been modified for the purpose of this tutorial&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This continues the [[NMLTutorial/Train three part articulated|third part]] of the train example. The three part EMU will be made refittable to a four part EMU.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== What&#039;s going to happen ==&lt;br /&gt;
A lot of things need to be added to make this train refittable between three and four parts.&lt;br /&gt;
&lt;br /&gt;
The method used to do this is actually the other way round than the user will think from the behaviour ingame. The train will be changed to a four part EMU. For the (default) three part refit one of these four parts will be hidden. A lot of switches will be used to make the train look right, make it have the correct capacity, power, weight, running costs and tractive effort.&lt;br /&gt;
&lt;br /&gt;
There are some drawbacks to this method. There&#039;s no way to charge the user for puchasing the extra vehicle part. Also autoreplacing will be difficult, as there&#039;s now way for the user to select which vehicle length they want. For that reason the author of this tutorial thinks making two different vehicles and having both available from the purchase menu is a better solution, but this method is a good illustration for some of the more advanced features of NML. It&#039;s up to you to decide which implementation you think is best for your vehicles.&lt;br /&gt;
&lt;br /&gt;
What we&#039;ll be doing:&lt;br /&gt;
* Add the refit option;&lt;br /&gt;
* Make the graphics work;&lt;br /&gt;
* Add callbacks to supply the correct vehicle properties;&lt;br /&gt;
* Make the purchase menu display the correct values.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Refit option ==&lt;br /&gt;
The refit option will be added by means of the &amp;quot;cargo subtype&amp;quot;. This allows to split each cargo into multiple entities which can be assigned different properties by means of other callbacks.&lt;br /&gt;
&lt;br /&gt;
The first step towards this is defining names for these separate entries using the &amp;lt;code&amp;gt;cargo_subtype_text&amp;lt;/code&amp;gt; [http://newgrf-specs.tt-wiki.net/wiki/NML:Vehicles#Vehicle_callbacks callback]. This callback requires the use of a switch, so reference a switch from the graphics block:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
        cargo_subtype_text:           sw_icm_cargo_subtype_text;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The switch itself will use the &amp;lt;code&amp;gt;cargo_subtype&amp;lt;/code&amp;gt; [http://newgrf-specs.tt-wiki.net/wiki/NML:Vehicles#Vehicle_variables variable]. This variable starts at 0 and will be increased by 1 until the callback returns &amp;lt;code&amp;gt;CB_RESULT_NO_MORE_ARTICULATED_PARTS&amp;lt;/code&amp;gt;. Return strings to use as cargo subtype. Each returned string will be a separate cargo subtype:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_cargo_subtype_text, cargo_subtype) {&lt;br /&gt;
    0: return string(STR_ICM_SUBTYPE_3_PART);&lt;br /&gt;
    1: return string(STR_ICM_SUBTYPE_4_PART);&lt;br /&gt;
    return CB_RESULT_NO_MORE_ARTICULATED_PARTS;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This adds two cargo subtypes. Also add these strings to the language file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
STR_ICM_SUBTYPE_3_PART       : (3 parts)&lt;br /&gt;
STR_ICM_SUBTYPE_4_PART       : (4 parts)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Graphics ==&lt;br /&gt;
The graphics defined previously were for a three part vehicle. Now we have to make this into a four part vehicle and hide one wagon for the three part refit.&lt;br /&gt;
&lt;br /&gt;
=== Four part articulated vehicle ===&lt;br /&gt;
In order to make the vehicle four parts, the articulated vehicle callback switch needs to be changed:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_articulated_part, extra_callback_info1) {&lt;br /&gt;
    /* Add three articulated parts, for a total of four */&lt;br /&gt;
    1 .. 3: return item_icm;&lt;br /&gt;
    return CB_RESULT_NO_MORE_ARTICULATED_PARTS;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is done by changing the value range from &amp;lt;code&amp;gt;1 .. 2&amp;lt;/code&amp;gt; into &amp;lt;code&amp;gt;1 .. 3&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Start/stop callback ===&lt;br /&gt;
The start/stop callback checking the vehicle length needs to be changed as well. If we still want a maximum of four EMUs, the maximum length will now be 4 * 4 instead of 4 * 3. This means changing the switch for this callback:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_start_stop, num_vehs_in_consist) {&lt;br /&gt;
    /* Vehicles may be coupled to a maximum of 4 units (12-16 cars) */&lt;br /&gt;
    1 .. 16: return CB_RESULT_NO_TEXT;&lt;br /&gt;
    return string(STR_ICM_CANNOT_START);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is done by changing the value range from &amp;lt;code&amp;gt;1 .. 12&amp;lt;/code&amp;gt; into &amp;lt;code&amp;gt;1 .. 16&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Graphics ===&lt;br /&gt;
Now that the vehicle is four parts, the default graphics switch needs to be changed as well to allow for two middle parts instead of one:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_graphics, position_in_consist % 4) {&lt;br /&gt;
    0:      set_icm_front_lighted;&lt;br /&gt;
    3:      set_icm_rear_lighted;&lt;br /&gt;
    sw_icm_graphics_middle;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Instead of modulo 3 we&#039;re now taking modulo 4. And the value for the rear vehicle part was changed from 2 to 3. For the middle parts, we also need to hide the one of the wagons for the three part EMU. Therefore we can&#039;t directly reference the spriteset but need an extra intermediate switch block.&lt;br /&gt;
&lt;br /&gt;
The extra switch block:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_graphics_middle, ((position_in_consist % 4) == 2) &amp;amp;&amp;amp; (cargo_subtype == 0)) {&lt;br /&gt;
    1: set_icm_invisible;&lt;br /&gt;
    set_icm_middle;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Even an expression this advanced can be used for switch block decision. Here we again check the position of the vehicle part, but also which cargo subtype is used for this vehicle. If it is the three part EMU (cargo subtype 0) AND it is the third vehicle part (position 2 counting from 0), we hide this vehicle part by displaying no graphics for it. In all other cases we display the regular middle part.&lt;br /&gt;
&lt;br /&gt;
=== Vehicle length ===&lt;br /&gt;
If you were to encode the result so far as a NewGRF, you end up with a three part train that has a big gap between the second and last part. This is because it&#039;s essentially still a four part vehicle, just with no graphics for the third part. This can be solved by changing the length of the two middle parts. If we make the second part (7/8) long and the third part (1/8), both together are a full wagon length, completely hiding the invisible third part.&lt;br /&gt;
&lt;br /&gt;
This is done by means of the &amp;lt;code&amp;gt;shorten_vehicle&amp;lt;/code&amp;gt; [http://newgrf-specs.tt-wiki.net/wiki/NML:Vehicles#Vehicle_callbacks callback], referencing a switch block as we first need to differentiate between the two cargo subtypes and then by the position in consist. Reference the switch block from the graphics block:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
        shorten_vehicle:              sw_icm_shorten_vehicle;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then we get the two switch blocks:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
/* --- Shorten vehicle callback  --- */&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_shorten_3_part_vehicle, position_in_consist % 4) {&lt;br /&gt;
    /* In the three part version, shorten the 2nd vehicle to 7/8 and the 3rd to 1/8&lt;br /&gt;
     * The rear (1/8) part is then made invisisble */&lt;br /&gt;
    1: return SHORTEN_TO_7_8;&lt;br /&gt;
    2: return SHORTEN_TO_1_8;&lt;br /&gt;
    return SHORTEN_TO_8_8;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_shorten_vehicle, cargo_subtype) {&lt;br /&gt;
    0: sw_icm_shorten_3_part_vehicle;&lt;br /&gt;
    return SHORTEN_TO_8_8; // 4-part vehicle needs no shortening&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The second of these switch blocks (called first from the graphics block) differentiates between the two cargo subtypes. For subtype 0 (three part vehicle) we need to do the shortenings and reference the first switch block. For the four part vehicle we need no shortening, so directly return to &amp;quot;shorten&amp;quot; to full length.&lt;br /&gt;
&lt;br /&gt;
The first switch again makes a decision based on the &amp;lt;code&amp;gt;position_in_consist&amp;lt;/code&amp;gt; [http://newgrf-specs.tt-wiki.net/wiki/NML:Vehicles#Vehicle_variables variable] we&#039;ve seen several times now. As said, the second part will be shortened to (7/8), the third part to (1/8) and the front and back part are kept full length (8/8).&lt;br /&gt;
&lt;br /&gt;
Now the vehicle looks good in both refits.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Vehicle properties ==&lt;br /&gt;
Both refits still have identical properties. Surely the four part EMU has a higher capacity. We&#039;ll also change the running costs, power, weight and tractive effort depending on the refit chosen. This is all done by callbacks. You can find the available vehicle callbacks [http://newgrf-specs.tt-wiki.net/wiki/NML:Vehicles#Vehicle_callbacks here], with the second table especially on callbacks that change certain properties.&lt;br /&gt;
&lt;br /&gt;
=== Running cost factor ===&lt;br /&gt;
You can easily imagine that the longer vehicle will be more expensive to run. The three part has a running cost factor of 100, the four part will get a factor of 150. This requires adding the &amp;lt;code&amp;gt;running_cost_factor&amp;lt;/code&amp;gt; callback to the graphics block. From there we can link to a switch block and base the decision on the &amp;lt;code&amp;gt;cargo_subtype&amp;lt;/code&amp;gt; [http://newgrf-specs.tt-wiki.net/wiki/NML:Vehicles#Vehicle_variables variable]. A different method as shown below is not to use a switch block but to make the decision directly from the graphics block using a conditional assignment. We&#039;ve used a conditional assignment [[Train_single_engine#Templates|before]] in one of the template blocks.&lt;br /&gt;
&lt;br /&gt;
Add to the graphics block:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
        running_cost_factor:          return (cargo_subtype == 1) ? 150 : 100;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In case the &amp;lt;code&amp;gt;cargo_subtype&amp;lt;/code&amp;gt; is 1 (the four part vehicle), a running cost factor of 150 is used. Otherwise, a factor of 100 is used. If you&#039;d rather used a switch block then that&#039;s up to you. Just reference one from the graphics block instead of the conditional assignment and use the switch block to make the decision based on the &amp;lt;code&amp;gt;cargo_subtype&amp;lt;/code&amp;gt; variable.&lt;br /&gt;
&lt;br /&gt;
=== Cargo capacity ===&lt;br /&gt;
The cargo capacity is 36 passengers per unit. Now the three part EMU will have a capacity that is too high, because it technically is a four part EMU with one part hidden. We need to give this hidden part 0 capacity.&lt;br /&gt;
&lt;br /&gt;
This is done by the &amp;lt;code&amp;gt;cargo_capacity&amp;lt;/code&amp;gt; callback. If the &amp;lt;code&amp;gt;cargo_subtype&amp;lt;/code&amp;gt; is 0 and the &amp;lt;code&amp;gt;position_in_consist&amp;lt;/code&amp;gt; is the third part, we give it 0 capacity. Else it will get 36 capacity. Also this can be done directly from the graphics block, using a slightly more advanced conditional assignment. Of course you could again have used a switch block here, but there&#039;s no need for that in this case.&lt;br /&gt;
&lt;br /&gt;
Add to the graphics block:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
cargo_capacity:               return (cargo_subtype == 0) &amp;amp;&amp;amp; ((position_in_consist % 4) == 2) ? 0 : 36;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Power ===&lt;br /&gt;
The power of the four part vehicle will be higher. Let&#039;s use a switch block this time. Of course a conditional assignment could be used here, but compare this example with the running cost factor yourself. The callback used here is called &amp;lt;code&amp;gt;power&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Reference the switch block from the graphics block:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
        power:                        sw_icm_power;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The switch block itself will again make a decision based on the &amp;lt;code&amp;gt;cargo_subtype&amp;lt;/code&amp;gt; variable. The callback must return the vehicle power in horsepower (imperial) and this must be an integer value. Because we know the power in kW, a little calculation is needed which NML can do for you. Returning the integer is done by the &amp;lt;code&amp;gt;int()&amp;lt;/code&amp;gt; function that turns a (decimal) number into an integer.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_power, cargo_subtype) {&lt;br /&gt;
    0: return int(1260 / 0.7457); // kW -&amp;gt; hp&lt;br /&gt;
    return int(1890 / 0.7457); // kW -&amp;gt; hp&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Weight ===&lt;br /&gt;
Of course you could have done the calculation yourself and put the rounded values in the switch block. That we&#039;ll do for the weight of the vehicle. The callback used here is called &amp;lt;code&amp;gt;weight&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Again, reference the switch block from the graphics block:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
weight:                       sw_icm_weight;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The switch block itself will again make a decision based on the &amp;lt;code&amp;gt;cargo_subtype&amp;lt;/code&amp;gt; variable. The weight here must be specified in tons:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_weight, cargo_subtype) {&lt;br /&gt;
    0: return 144; //ton, 3 part train&lt;br /&gt;
    return 192; //ton, 4 part train&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Tractive effort coefficient===&lt;br /&gt;
The last property to sort out is the tractive effort. The callback used here is called &amp;lt;code&amp;gt;tractive_effort_coefficient&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Again, reference the switch block from the graphics block:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
        tractive_effort_coefficient:  sw_icm_te;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the switch block we&#039;ll actually calculate the tractive effort coefficient:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_te, cargo_subtype) {&lt;br /&gt;
    /* Base TE coefficient = 0.3&lt;br /&gt;
     * 3 parts: 4/12 of weight on driving wheels&lt;br /&gt;
     * 4 parts: 6/16 of weight on driving wheels */&lt;br /&gt;
    0: return int(0.3 * 255 / 3);&lt;br /&gt;
    return int(0.3 * 255 * 3 / 8);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;The technical background of the tractive effort coefficient is that it must be supplied as value between 0 and 255, with 255 equal to 100%. The tractive effort coefficient itself is calculated by multiplying the friction coefficient (see [http://en.wikipedia.org/wiki/Rail_adhesion Wikipedia] for it&#039;s meaning) with the percentage of weight that is on driven wheels. I this case we use a friction of 30%. In real life the three part vehicle has 12 axles of which 4 powered. The four part vehicle has 16 axles of which 6 powered. Assuming an equal distribution of weight along the length of the vehicle, the three part vehicle has 33.3% of it&#039;s weight on powered wheels. The four part vehicle has 37.5% of it&#039;s weight on powered wheels. Multiply both by the friction coefficient and the factor of 255 and you have the tractive effort coefficient.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;If you don&#039;t provide a tractive effort coefficient, the game will assume a friction coefficient of 0.3 and all axles powered. A tractive effort coefficient of 100% you&#039;ll only get with 100% friction and and all axles powered. This is unrealistic for railroads but can be used for maglev when there actually is no contact between vehicle and guideway.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Purchase menu ==&lt;br /&gt;
With all these callbacks we&#039;ve sort of broken the display of properties in the purchase menu. This is because the &amp;lt;code&amp;gt;position_in_consist&amp;lt;/code&amp;gt; [http://newgrf-specs.tt-wiki.net/wiki/NML:Vehicles#Vehicle_variables variable] is not available in the purchase menu and &amp;lt;code&amp;gt;cargo_subtype&amp;lt;/code&amp;gt; variable is always 0 in the purchase menu. The latter can be to our advantage if we want to display the properties of the shorter refit, but the other needs some fixing.&lt;br /&gt;
&lt;br /&gt;
=== Running cost factor ===&lt;br /&gt;
This callback was only based on &amp;lt;code&amp;gt;cargo_subtype&amp;lt;/code&amp;gt;, so no fixing needed here.&lt;br /&gt;
&lt;br /&gt;
=== Cargo capacity ===&lt;br /&gt;
The capacity used both variables, so some fixing is in order here. We want to display 36*3 as capacity. Because capacity is defined per unit and our vehicle is technically four units, we need to divide this over four units: 36*3/4. Add the &amp;lt;code&amp;gt;purchase_cargo_capacity&amp;lt;/code&amp;gt; [http://newgrf-specs.tt-wiki.net/wiki/NML:Vehicles#Vehicle_callbacks callback] to the graphics block and return this value:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
        purchase_cargo_capacity:      return 36 * 3 / 4;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Power, weight and tractive effort coefficient ===&lt;br /&gt;
Luckily, these are also only based on the cargo subtype variable, so no fixing needed. If you wanted a different value to be displayed in the purchase menu, you&#039;d use the &amp;lt;code&amp;gt;purchase_power&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;purchase_weight&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;purchase_tractive_effort_coefficient&amp;lt;/code&amp;gt; [http://newgrf-specs.tt-wiki.net/wiki/NML:Vehicles#Vehicle_callbacks callbacks] to do this. And if you want to know, the running cost factor would logically use the &amp;lt;code&amp;gt;purchase_running_cost_factor&amp;lt;/code&amp;gt; callback.&lt;br /&gt;
&lt;br /&gt;
=== Additional text ===&lt;br /&gt;
We want to inform the user that this train has an option to refit it into a four part version and that the properties shown are for the three part version. For this we&#039;ll use the &amp;lt;code&amp;gt;additional_text&amp;lt;/code&amp;gt; [http://newgrf-specs.tt-wiki.net/wiki/NML:Vehicles#Vehicle_callbacks callback] which we also used in the tram example. It can directly return a string from the graphics block:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
        additional_text:              return string(STR_ICM_ADDITIONAL_TEXT);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Also don&#039;t forget to add this string to the language file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
STR_ICM_ADDITIONAL_TEXT      :Choose between 3- and 4-part EMU via refit{}Stated values are for the 3-part variant, the 4-part version has 33% more capacity and 50% more power and running cost.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This means our vehicle now works like it should with the two refits. Encode it into a NewGRF if you like.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Total code so far ==&lt;br /&gt;
When put in the correct order, this should now encode as a working NewGRF. The total code so far:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap; max-height: 200px; overflow:scroll&amp;quot;&amp;gt;&lt;br /&gt;
/* Define grf */&lt;br /&gt;
grf {&lt;br /&gt;
    grfid: &amp;quot;NML\00&amp;quot;;&lt;br /&gt;
    /* GRF name and description strings are defined in the lang files */&lt;br /&gt;
    name: string(STR_GRF_NAME);&lt;br /&gt;
    desc: string(STR_GRF_DESC);&lt;br /&gt;
    /* This is the first version, start numbering at 0. */&lt;br /&gt;
    version: 0;&lt;br /&gt;
    min_compatible_version: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Define a rail type table,&lt;br /&gt;
 * this allows referring to railtypes&lt;br /&gt;
 * irrespective of the grfs loaded.&lt;br /&gt;
 */&lt;br /&gt;
railtypetable {&lt;br /&gt;
    ELRL&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Basic template for 4 vehicle views */&lt;br /&gt;
template tmpl_vehicle_basic(x, y) {&lt;br /&gt;
    // arguments x, y: coordinates of top-left corner of first sprite&lt;br /&gt;
    [x,      y,  8, 24,  -3, -12] //xpos ypos xsize ysize xrel yrel&lt;br /&gt;
    [x +  9, y, 22, 20, -14, -12]&lt;br /&gt;
    [x + 32, y, 32, 16, -16, -12]&lt;br /&gt;
    [x + 65, y, 22, 20,  -6, -12]&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Template for a vehicle with only 4 views (symmetric) */&lt;br /&gt;
template tmpl_vehicle_4_views(num) {&lt;br /&gt;
    // argument num: Index in the graphics file, assuming vertical ordering of vehicles&lt;br /&gt;
    tmpl_vehicle_basic(1, 1 + 32 * num)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Template for a vehicle with 8 views (non-symmetric) */&lt;br /&gt;
template tmpl_vehicle_8_views(num, reversed) {&lt;br /&gt;
    // argument num: Index in the graphics file, assuming vertical ordering of vehicles&lt;br /&gt;
    // argument reversed: Reverse visible orientation of vehicle, if set to 1&lt;br /&gt;
    tmpl_vehicle_basic(reversed ? 89 : 1, 1 + 32 * num)&lt;br /&gt;
    tmpl_vehicle_basic(reversed ? 1 : 89, 1 + 32 * num)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Template for a single vehicle sprite */&lt;br /&gt;
template tmpl_vehicle_single(num, xsize, ysize, xoff, yoff) {&lt;br /&gt;
    [1, 1 + 32 * num, xsize, ysize, xoff, yoff]&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Define the spritesets, these allow referring to these sprites later on */&lt;br /&gt;
spriteset (set_icm_front_lighted, &amp;quot;gfx/icm.png&amp;quot;) { tmpl_vehicle_8_views(0, 0) }&lt;br /&gt;
spriteset (set_icm_rear_lighted,  &amp;quot;gfx/icm.png&amp;quot;) { tmpl_vehicle_8_views(1, 1) }&lt;br /&gt;
spriteset (set_icm_front,         &amp;quot;gfx/icm.png&amp;quot;) { tmpl_vehicle_8_views(2, 0) }&lt;br /&gt;
spriteset (set_icm_rear,          &amp;quot;gfx/icm.png&amp;quot;) { tmpl_vehicle_8_views(3, 1) }&lt;br /&gt;
spriteset (set_icm_middle,        &amp;quot;gfx/icm.png&amp;quot;) { tmpl_vehicle_4_views(4)    }&lt;br /&gt;
spriteset (set_icm_purchase,      &amp;quot;gfx/icm.png&amp;quot;) { tmpl_vehicle_single(5, 53, 14, -25, -10) }&lt;br /&gt;
spriteset (set_icm_invisible,     &amp;quot;gfx/icm.png&amp;quot;) { tmpl_vehicle_single(6,  1,  1,   0,   0) }&lt;br /&gt;
&lt;br /&gt;
/* --- Graphics callback  --- */&lt;br /&gt;
&lt;br /&gt;
/* In the 3-part version, the 3rd car is invisible */&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_graphics_middle, ((position_in_consist % 4) == 2) &amp;amp;&amp;amp; (cargo_subtype == 0)) {&lt;br /&gt;
    1: set_icm_invisible;&lt;br /&gt;
    set_icm_middle;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Choose between front, middle and back parts */&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_graphics, position_in_consist % 4) {&lt;br /&gt;
    0:      set_icm_front_lighted;&lt;br /&gt;
    3:      set_icm_rear_lighted;&lt;br /&gt;
    set_icm_middle;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* --- Cargo subtype text --- */&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_cargo_subtype_text, cargo_subtype) {&lt;br /&gt;
    0: return string(STR_ICM_SUBTYPE_3_PART);&lt;br /&gt;
    1: return string(STR_ICM_SUBTYPE_4_PART);&lt;br /&gt;
    return CB_RESULT_NO_TEXT;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* --- Articulated part callback  --- */&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_articulated_part, extra_callback_info1) {&lt;br /&gt;
    /* Add three articulated parts, for a total of four */&lt;br /&gt;
    1 .. 3: return item_icm;&lt;br /&gt;
    return CB_RESULT_NO_MORE_ARTICULATED_PARTS;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* --- Start/stop callback  --- */&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_start_stop, num_vehs_in_consist) {&lt;br /&gt;
    /* Vehicles may be coupled to a maximum of 4 units (12-16 cars) */&lt;br /&gt;
    1 .. 16: return CB_RESULT_NO_TEXT;&lt;br /&gt;
    return string(STR_ICM_CANNOT_START);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* --- Wagon attach callback  --- */&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_can_attach_wagon, vehicle_type_id) {&lt;br /&gt;
    /* SELF refers to the wagon here, check that it&#039;s an ICM */&lt;br /&gt;
    item_icm: return CB_RESULT_ATTACH_ALLOW;&lt;br /&gt;
    return string(STR_ICM_CANNOT_ATTACH_OTHER);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* --- Shorten vehicle callback  --- */&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_shorten_3_part_vehicle, position_in_consist % 4) {&lt;br /&gt;
    /* In the three part version, shorten the 2nd vehicle to 7/8 and the 3rd to 1/8&lt;br /&gt;
     * The rear (1/8) part is then made invisisble */&lt;br /&gt;
    1: return SHORTEN_TO_7_8;&lt;br /&gt;
    2: return SHORTEN_TO_1_8;&lt;br /&gt;
    return SHORTEN_TO_8_8;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_shorten_vehicle, cargo_subtype) {&lt;br /&gt;
    0: sw_icm_shorten_3_part_vehicle;&lt;br /&gt;
    return SHORTEN_TO_8_8; // 4-part vehicle needs no shortening&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Power, weight and TE are all applied to the front vehicle only */&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_power, cargo_subtype) {&lt;br /&gt;
    0: return int(1260 / 0.7457); // kW -&amp;gt; hp&lt;br /&gt;
    return int(1890 / 0.7457); // kW -&amp;gt; hp&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_weight, cargo_subtype) {&lt;br /&gt;
    0: return 144; //ton, 3 part train&lt;br /&gt;
    return 192; //ton, 4 part train&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_te, cargo_subtype) {&lt;br /&gt;
    /* Base TE coefficient = 0.3&lt;br /&gt;
     * 3 parts: 4/12 of weight on driving wheels&lt;br /&gt;
     * 4 parts: 6/16 of weight on driving wheels */&lt;br /&gt;
    0: return int(0.3 * 255 / 3);&lt;br /&gt;
    return int(0.3 * 255 * 3 / 8);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Define the actual train */&lt;br /&gt;
item(FEAT_TRAINS, item_icm) {&lt;br /&gt;
    /* Define properties first, make sure to set all of them */&lt;br /&gt;
    property {&lt;br /&gt;
        name:                         string(STR_ICM_NAME);&lt;br /&gt;
        // not available in toyland:&lt;br /&gt;
        climates_available:           bitmask(CLIMATE_TEMPERATE, CLIMATE_ARCTIC, CLIMATE_TROPICAL); &lt;br /&gt;
        introduction_date:            date(1983, 1, 1);&lt;br /&gt;
        model_life:                   VEHICLE_NEVER_EXPIRES;&lt;br /&gt;
        vehicle_life:                 30;&lt;br /&gt;
        reliability_decay:            20;&lt;br /&gt;
        refittable_cargo_classes:     bitmask(CC_PASSENGERS);&lt;br /&gt;
        non_refittable_cargo_classes: bitmask();&lt;br /&gt;
        // refitting is done via cargo classes only, no cargoes need explicit enabling/disabling:&lt;br /&gt;
        refittable_cargo_types:       bitmask(); &lt;br /&gt;
        // It&#039;s an intercity train, loading is relatively slow:&lt;br /&gt;
        loading_speed:                6; &lt;br /&gt;
        cost_factor:                  45;&lt;br /&gt;
        running_cost_factor:          100; // Changed by callback&lt;br /&gt;
        sprite_id:                    SPRITE_ID_NEW_TRAIN;&lt;br /&gt;
        speed:                        141 km/h; // actually 140, but there are rounding errors&lt;br /&gt;
        misc_flags:                   bitmask(TRAIN_FLAG_2CC, TRAIN_FLAG_MU);&lt;br /&gt;
        refit_cost:                   0; //refit costs don&#039;t apply to subcargo display &lt;br /&gt;
        // callback flags are not set manually&lt;br /&gt;
        track_type:                   ELRL; // from rail type table&lt;br /&gt;
        ai_special_flag:              AI_FLAG_PASSENGER;&lt;br /&gt;
        power:                        1260 kW; // Changed by CB&lt;br /&gt;
        running_cost_base:            RUNNING_COST_ELECTRIC;&lt;br /&gt;
        dual_headed:                  0;&lt;br /&gt;
        cargo_capacity:               36; // per part, changed by callback&lt;br /&gt;
        weight:                       144 ton; // Total, changed by callback&lt;br /&gt;
        ai_engine_rank:               0; // not intended to be used by the ai&lt;br /&gt;
        engine_class:                 ENGINE_CLASS_ELECTRIC;&lt;br /&gt;
        extra_power_per_wagon:        0 kW;&lt;br /&gt;
        // 4/12 of weight on driving wheels, with a default friction coefficient of 0.3:&lt;br /&gt;
        tractive_effort_coefficient:  0.3 / 3; // changed by callback&lt;br /&gt;
        air_drag_coefficient:         0.06;&lt;br /&gt;
        shorten_vehicle:              SHORTEN_TO_8_8;&lt;br /&gt;
        // Overridden by callback to disable for non-powered wagons:&lt;br /&gt;
        visual_effect_and_powered:    visual_effect_and_powered(VISUAL_EFFECT_ELECTRIC, 2, DISABLE_WAGON_POWER);&lt;br /&gt;
        extra_weight_per_wagon:       0 ton;&lt;br /&gt;
        bitmask_vehicle_info:         0;&lt;br /&gt;
    }&lt;br /&gt;
    /* Define graphics and callbacks&lt;br /&gt;
     * Setting all callbacks is not needed, only define what is used */&lt;br /&gt;
    graphics {&lt;br /&gt;
        default:                      sw_icm_graphics;&lt;br /&gt;
        purchase:                     set_icm_purchase;&lt;br /&gt;
        cargo_subtype_text:           sw_icm_cargo_subtype_text;&lt;br /&gt;
        additional_text:              return string(STR_ICM_ADDITIONAL_TEXT);&lt;br /&gt;
        start_stop:                   sw_icm_start_stop;&lt;br /&gt;
        articulated_part:             sw_icm_articulated_part;&lt;br /&gt;
        can_attach_wagon:             sw_icm_can_attach_wagon;&lt;br /&gt;
        running_cost_factor:          return (cargo_subtype == 1) ? 150 : 100;&lt;br /&gt;
        /* Capacity is per part */&lt;br /&gt;
        cargo_capacity:               return (cargo_subtype == 0) &amp;amp;&amp;amp; ((position_in_consist % 4) == 2) ? 0 : 36;&lt;br /&gt;
        /* In the purchase menu, we want to show the capacity for the three-part version,&lt;br /&gt;
         * i.e. divide the capacity of three cars across four */&lt;br /&gt;
        purchase_cargo_capacity:      return 36 * 3 / 4;&lt;br /&gt;
        /* Only the front vehicle has a visual effect */&lt;br /&gt;
        shorten_vehicle:              sw_icm_shorten_vehicle;&lt;br /&gt;
        /* Only the front vehicle has power */&lt;br /&gt;
        power:                        sw_icm_power;&lt;br /&gt;
        /* Only the front vehicle has weight */&lt;br /&gt;
        weight:                       sw_icm_weight;&lt;br /&gt;
        /* Only the front vehicle has TE */&lt;br /&gt;
        tractive_effort_coefficient:  sw_icm_te;&lt;br /&gt;
        /* Only 1/3 of the weight is on the driving weels. */&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Language file so far ===&lt;br /&gt;
english.lng now contains this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap; max-height: 200px; overflow:scroll&amp;quot;&amp;gt;&lt;br /&gt;
##grflangid 0x01&lt;br /&gt;
&lt;br /&gt;
STR_GRF_NAME                 :NML Example NewGRF: Train&lt;br /&gt;
STR_GRF_DESC                 :{ORANGE}NML Example NewGRF: Train{}{BLACK}This NewGRF is intended to provide a coding example for the high-level NewGRF-coding language NML.{}Original graphics by {SILVER}Purno, {BLACK}coding by {SILVER}DJNekkid.{}{BLACK}This NewGRF defines a Dutch EMU, the ICM &#039;Koploper&#039;.&lt;br /&gt;
&lt;br /&gt;
STR_ICM_NAME                 :ICM &#039;Koploper&#039; (Electric)&lt;br /&gt;
STR_ICM_ADDITIONAL_TEXT      :Choose between 3- and 4-part EMU via refit{}Stated values are for the 3-part variant, the 4-part version has 33% more capacity and 50% more power and running cost.&lt;br /&gt;
STR_ICM_SUBTYPE_3_PART       : (3 parts)&lt;br /&gt;
STR_ICM_SUBTYPE_4_PART       : (4 parts)&lt;br /&gt;
STR_ICM_CANNOT_START         :... train too long (max. 4 coupled EMUs).&lt;br /&gt;
STR_ICM_CANNOT_ATTACH_OTHER  :... only other ICMs can be attached to ICM.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you like, this train is done. If you like to continue, you can learn about GRF parameters and then we&#039;ll add a parameter setting to display this train in either 1cc, 2cc or real life colours.&lt;br /&gt;
&lt;br /&gt;
{{NMLTutorialNavbar|Train three part articulated|Parameters}}&lt;/div&gt;</summary>
		<author><name>Yexo</name></author>
	</entry>
	<entry>
		<id>https://www.tt-wiki.net/index.php?title=NMLTutorial/Train_three_part_articulated&amp;diff=7983</id>
		<title>NMLTutorial/Train three part articulated</title>
		<link rel="alternate" type="text/html" href="https://www.tt-wiki.net/index.php?title=NMLTutorial/Train_three_part_articulated&amp;diff=7983"/>
		<updated>2011-12-13T22:30:44Z</updated>

		<summary type="html">&lt;p&gt;Yexo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{NMLTutorial}}&lt;br /&gt;
&#039;&#039;The example used here is from the [http://dev.openttdcoop.org/projects/nml/repository/show/examples NML source]. The code for this was originally written in NFO by DJNekkid for the 2cc Trainset and rewritten in NML by Hirundo. The graphics used in the example are by Purno. Code and graphics are both licensed according to the GPL v2 or later. The code has been modified for the purpose of this tutorial&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This continues the [[NMLTutorial/Train single engine|second part]] of the train example. The train will be made into an articulated EMU that can be purchased all at once.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Callbacks ==&lt;br /&gt;
Except the articulated vehicle callback, we&#039;ll add two more callbacks to only allow attaching more of these multiple units (and not other trains/wagons) and to give the train a maximum length.&lt;br /&gt;
&lt;br /&gt;
The callbacks and switch blocks that are needed for this will be discussed below. What callbacks are available for vehicles can be found in the [http://newgrf-specs.tt-wiki.net/wiki/NML:Vehicles#Vehicle_callbacks NML Documentation]. From here you can decide what callbacks suit your needs and find their names to be used in the graphics block.&lt;br /&gt;
&lt;br /&gt;
=== Articulated part callback ===&lt;br /&gt;
We have seen this one before in the tram example. Returning a single value is not enough for this callback, so we need to reference a switch block to handle the callback.&lt;br /&gt;
&lt;br /&gt;
Add to the graphics block:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
        articulated_part:             sw_icm_articulated_part;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The callback needs to return the identifier of a vehicle for as long as you want to keep adding parts and return &amp;lt;code&amp;gt;CB_RESULT_NO_MORE_ARTICULATED_PARTS&amp;lt;/code&amp;gt; to stop the process. During the callback the game will continuously call the callback, each time increasing the &amp;lt;code&amp;gt;extra_callback_info1&amp;lt;/code&amp;gt; [http://newgrf-specs.tt-wiki.net/wiki/NML:General variable] by one.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_articulated_part, extra_callback_info1) {&lt;br /&gt;
    /* Add two articulated parts, for a total of three */&lt;br /&gt;
    1 .. 2: return item_icm;&lt;br /&gt;
    return CB_RESULT_NO_MORE_ARTICULATED_PARTS;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This causes the callback to be called three times, adding two extra parts to the &amp;lt;code&amp;gt;item_icm&amp;lt;/code&amp;gt; vehicle. For an extended explanation of this, see the tram example.&lt;br /&gt;
&lt;br /&gt;
=== Start/stop callback ===&lt;br /&gt;
The start/stop callback is called whenever a vehicle is started in the depot and decides if the vehicle may leave the depot. The callback must return &amp;lt;code&amp;gt;0xFF&amp;lt;/code&amp;gt; to allow the vehicle to leave the depot. If you want to prevent the vehicle from leaving the depot, the callback must return a string containing an error message.&lt;br /&gt;
&lt;br /&gt;
We want to use this callback to check the vehicle length. As such it makes sense to base the decision on the length of the train, which can be found using the &amp;lt;code&amp;gt;num_vehs_in_consist&amp;lt;/code&amp;gt; [http://newgrf-specs.tt-wiki.net/wiki/NML:Vehicles#Vehicle_variables variable]. Because we need to base a decision on some variable, we&#039;ll use a switch block to do that.&lt;br /&gt;
&lt;br /&gt;
Add to the graphics block:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
        start_stop:                   sw_icm_start_stop;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We want to limit our train length to a maximum of four coupled EMUs. As each EMU has a length of three, the total possible train length is twelve. So for train lengths 1 to 12 we want to return &amp;lt;code&amp;gt;CB_RESULT_NO_TEXT&amp;lt;/code&amp;gt; (and allow the train to leave the depot). For any other train length we return a string to disallow starting the train and informing the user why that is.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_start_stop, num_vehs_in_consist) {&lt;br /&gt;
    /* Vehicles may be coupled to a maximum of 4 units (12 cars) */&lt;br /&gt;
    1 .. 12: return CB_RESULT_NO_TEXT;&lt;br /&gt;
    return string(STR_ICM_CANNOT_START);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As we added a new string, define it in the language file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
STR_ICM_CANNOT_START         :... train too long (max. 4 coupled EMUs).&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Wagon attach callback ===&lt;br /&gt;
We only want to allow attaching more of the same EMUs to this train. Amongst others, the callback can return a custom string to disallow or return &amp;lt;code&amp;gt;CB_RESULT_ATTACH_ALLOW&amp;lt;/code&amp;gt; to allow attaching. The decision must be made on the basis of the identifier of the wagon that is being attached. We can use the &amp;lt;code&amp;gt;vehicle_type_id&amp;lt;/code&amp;gt; [http://newgrf-specs.tt-wiki.net/wiki/NML:Vehicles#Vehicle_variables variable] to make that decision, using a switch block.&lt;br /&gt;
&lt;br /&gt;
Add to the graphics block:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
        can_attach_wagon:             sw_icm_can_attach_wagon;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will be the switch block:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_can_attach_wagon, vehicle_type_id) {&lt;br /&gt;
    /* SELF refers to the wagon here, check that it&#039;s an ICM */&lt;br /&gt;
    item_icm: return CB_RESULT_ATTACH_ALLOW;&lt;br /&gt;
    return string(STR_ICM_CANNOT_ATTACH_OTHER);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the attached wagon is of the type &#039;&#039;item_icm&#039;&#039;, it is allowed. Otherwise, a custom error message is displayed. This obviously means that we have to add this message to the language file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
STR_ICM_CANNOT_ATTACH_OTHER  :... only other ICMs can be attached to ICM.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Graphics ==&lt;br /&gt;
The final step in making this work is adding the graphics for the second and third part of the train. This is the same as in the tram example: point to a switch from the graphics block, make a decision based on the &amp;lt;code&amp;gt;position_in_consist&amp;lt;/code&amp;gt; [http://newgrf-specs.tt-wiki.net/wiki/NML:Vehicles#Vehicle_variables variable] and point to the spritesets from there.&lt;br /&gt;
&lt;br /&gt;
We already have the graphics and spritesets defined, so that&#039;s no problem.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
/* Choose between front, middle and back parts */&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_graphics, position_in_consist % 3) {&lt;br /&gt;
    0:      set_icm_front_lighted;&lt;br /&gt;
    2:      set_icm_rear_lighted;&lt;br /&gt;
    set_icm_middle;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This particular switch block actually first does a calculation on the &amp;lt;code&amp;gt;position_in_consist&amp;lt;/code&amp;gt; variable before making a decision on the result of that calculation. Here the modulo 3 of the value of &amp;lt;code&amp;gt;position_in_consist&amp;lt;/code&amp;gt; is calculated (&amp;lt;code&amp;gt;%&amp;lt;/code&amp;gt; is the modulo operator, see [http://en.wikipedia.org/wiki/Modulo_operation Wikipedia] for more details on modulo but basically it&#039;s the remainder after devision (by three in this case)).&lt;br /&gt;
&lt;br /&gt;
So for the first three vehicle parts the expression will yield 0, 1 and 2. For part four through six, it will again yield 0, 1 and 2, etc. The callback decision is then made on these three values alone: for part 0 use graphics for the train front, for part 2 use graphics for the train end and for all other parts use graphics for the middle.&lt;br /&gt;
&lt;br /&gt;
Also don&#039;t forget to reference this switch instead of the spriteset directly from the graphics block:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
        default:                      sw_icm_graphics;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Purchase menu sprite ==&lt;br /&gt;
The spriteset for the purchase menu sprite is already there. We only need to reference it from the graphics block&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
        purchase:                     set_icm_purchase;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Total code so far ==&lt;br /&gt;
When put in the correct order, this should now encode as a working NewGRF. The total code so far:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap; max-height: 200px; overflow:scroll&amp;quot;&amp;gt;&lt;br /&gt;
/* Define grf */&lt;br /&gt;
grf {&lt;br /&gt;
    grfid: &amp;quot;NML\00&amp;quot;;&lt;br /&gt;
    /* GRF name and description strings are defined in the lang files */&lt;br /&gt;
    name: string(STR_GRF_NAME);&lt;br /&gt;
    desc: string(STR_GRF_DESC);&lt;br /&gt;
    /* This is the first version, start numbering at 0. */&lt;br /&gt;
    version: 0;&lt;br /&gt;
    min_compatible_version: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Define a rail type table,&lt;br /&gt;
 * this allows referring to railtypes&lt;br /&gt;
 * irrespective of the grfs loaded.&lt;br /&gt;
 */&lt;br /&gt;
railtypetable {&lt;br /&gt;
    RAIL, ELRL, MONO, MGLV,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Basic template for 4 vehicle views */&lt;br /&gt;
template tmpl_vehicle_basic(x, y) {&lt;br /&gt;
    // arguments x, y: coordinates of top-left corner of first sprite&lt;br /&gt;
    [x,      y,  8, 24,  -3, -12] //xpos ypos xsize ysize xrel yrel&lt;br /&gt;
    [x +  9, y, 22, 20, -14, -12]&lt;br /&gt;
    [x + 32, y, 32, 16, -16, -12]&lt;br /&gt;
    [x + 65, y, 22, 20,  -6, -12]&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Template for a vehicle with only 4 views (symmetric) */&lt;br /&gt;
template tmpl_vehicle_4_views(num) {&lt;br /&gt;
    // argument num: Index in the graphics file, assuming vertical ordering of vehicles&lt;br /&gt;
    tmpl_vehicle_basic(1, 1 + 32 * num)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Template for a vehicle with 8 views (non-symmetric) */&lt;br /&gt;
template tmpl_vehicle_8_views(num, reversed) {&lt;br /&gt;
    // argument num: Index in the graphics file, assuming vertical ordering of vehicles&lt;br /&gt;
    // argument reversed: Reverse visible orientation of vehicle, if set to 1&lt;br /&gt;
    tmpl_vehicle_basic(reversed ? 89 : 1, 1 + 32 * num)&lt;br /&gt;
    tmpl_vehicle_basic(reversed ? 1 : 89, 1 + 32 * num)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Template for a single vehicle sprite */&lt;br /&gt;
template tmpl_vehicle_single(num, xsize, ysize, xoff, yoff) {&lt;br /&gt;
    [1, 1 + 32 * num, xsize, ysize, xoff, yoff]&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Define the spritesets, these allow referring to these sprites later on */&lt;br /&gt;
spriteset (set_icm_front_lighted, &amp;quot;gfx/icm.png&amp;quot;) { tmpl_vehicle_8_views(0, 0) }&lt;br /&gt;
spriteset (set_icm_rear_lighted,  &amp;quot;gfx/icm.png&amp;quot;) { tmpl_vehicle_8_views(1, 1) }&lt;br /&gt;
spriteset (set_icm_front,         &amp;quot;gfx/icm.png&amp;quot;) { tmpl_vehicle_8_views(2, 0) }&lt;br /&gt;
spriteset (set_icm_rear,          &amp;quot;gfx/icm.png&amp;quot;) { tmpl_vehicle_8_views(3, 1) }&lt;br /&gt;
spriteset (set_icm_middle,        &amp;quot;gfx/icm.png&amp;quot;) { tmpl_vehicle_4_views(4)    }&lt;br /&gt;
spriteset (set_icm_purchase,      &amp;quot;gfx/icm.png&amp;quot;) { tmpl_vehicle_single(5, 53, 14, -25, -10) }&lt;br /&gt;
spriteset (set_icm_invisible,     &amp;quot;gfx/icm.png&amp;quot;) { tmpl_vehicle_single(6,  1,  1,   0,   0) }&lt;br /&gt;
&lt;br /&gt;
/* Choose between front, middle and back parts */&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_graphics, position_in_consist % 3) {&lt;br /&gt;
    0:      set_icm_front_lighted;&lt;br /&gt;
    2:      set_icm_rear_lighted;&lt;br /&gt;
    set_icm_middle;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* --- Articulated part callback  --- */&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_articulated_part, extra_callback_info1) {&lt;br /&gt;
    /* Add three articulated parts, for a total of four */&lt;br /&gt;
    1 .. 2: return item_icm;&lt;br /&gt;
    return CB_RESULT_NO_MORE_ARTICULATED_PARTS;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* --- Start/stop callback  --- */&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_start_stop, num_vehs_in_consist) {&lt;br /&gt;
    /* Vehicles may be coupled to a maximum of 4 units (12 cars) */&lt;br /&gt;
    1 .. 12: return CB_RESULT_NO_TEXT;&lt;br /&gt;
    return string(STR_ICM_CANNOT_START);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* --- Wagon attach callback  --- */&lt;br /&gt;
switch(FEAT_TRAINS, SELF, sw_icm_can_attach_wagon, vehicle_type_id) {&lt;br /&gt;
    /* SELF refers to the wagon here, check that it&#039;s an ICM */&lt;br /&gt;
    item_icm: return CB_RESULT_ATTACH_ALLOW;&lt;br /&gt;
    return string(STR_ICM_CANNOT_ATTACH_OTHER);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Define the actual train */&lt;br /&gt;
item(FEAT_TRAINS, item_icm) {&lt;br /&gt;
    /* Define properties first, make sure to set all of them */&lt;br /&gt;
    property {&lt;br /&gt;
        name:                         string(STR_ICM_NAME);&lt;br /&gt;
        // not available in toyland:&lt;br /&gt;
        climates_available:           bitmask(CLIMATE_TEMPERATE, CLIMATE_ARCTIC, CLIMATE_TROPICAL); &lt;br /&gt;
        introduction_date:            date(1983, 1, 1);&lt;br /&gt;
        model_life:                   VEHICLE_NEVER_EXPIRES;&lt;br /&gt;
        vehicle_life:                 30;&lt;br /&gt;
        reliability_decay:            20;&lt;br /&gt;
        refittable_cargo_classes:     bitmask(CC_PASSENGERS);&lt;br /&gt;
        non_refittable_cargo_classes: bitmask();&lt;br /&gt;
        // refitting is done via cargo classes only, no cargoes need explicit enabling/disabling:&lt;br /&gt;
        refittable_cargo_types:       bitmask(); &lt;br /&gt;
        // It&#039;s an intercity train, loading is relatively slow:&lt;br /&gt;
        loading_speed:                6; &lt;br /&gt;
        cost_factor:                  45;&lt;br /&gt;
        running_cost_factor:          100; // Changed by callback&lt;br /&gt;
        sprite_id:                    SPRITE_ID_NEW_TRAIN;&lt;br /&gt;
        speed:                        141 km/h; // actually 140, but there are rounding errors&lt;br /&gt;
        misc_flags:                   bitmask(TRAIN_FLAG_2CC, TRAIN_FLAG_MU);&lt;br /&gt;
        refit_cost:                   0; //refit costs don&#039;t apply to subcargo display &lt;br /&gt;
        // callback flags are not set manually&lt;br /&gt;
        track_type:                   ELRL; // from rail type table&lt;br /&gt;
        ai_special_flag:              AI_FLAG_PASSENGER;&lt;br /&gt;
        power:                        1260 kW; // Changed by CB&lt;br /&gt;
        running_cost_base:            RUNNING_COST_ELECTRIC;&lt;br /&gt;
        dual_headed:                  0;&lt;br /&gt;
        cargo_capacity:               36; // per part, changed by callback&lt;br /&gt;
        weight:                       144 ton; // Total, changed by callback&lt;br /&gt;
        ai_engine_rank:               0; // not intended to be used by the ai&lt;br /&gt;
        engine_class:                 ENGINE_CLASS_ELECTRIC;&lt;br /&gt;
        extra_power_per_wagon:        0 kW;&lt;br /&gt;
        // 4/12 of weight on driving wheels, with a default friction coefficient of 0.3:&lt;br /&gt;
        tractive_effort_coefficient:  0.3 / 3; // changed by callback&lt;br /&gt;
        air_drag_coefficient:         0.06;&lt;br /&gt;
        shorten_vehicle:              SHORTEN_TO_8_8;&lt;br /&gt;
        // Overridden by callback to disable for non-powered wagons:&lt;br /&gt;
        visual_effect_and_powered:    visual_effect_and_powered(VISUAL_EFFECT_ELECTRIC, 2, DISABLE_WAGON_POWER);&lt;br /&gt;
        extra_weight_per_wagon:       0 ton;&lt;br /&gt;
        bitmask_vehicle_info:         0;&lt;br /&gt;
    }&lt;br /&gt;
    /* Define graphics and callbacks&lt;br /&gt;
     * Setting all callbacks is not needed, only define what is used */&lt;br /&gt;
    graphics {&lt;br /&gt;
        default:                      sw_icm_graphics;&lt;br /&gt;
        purchase:                     set_icm_purchase;&lt;br /&gt;
        start_stop:                   sw_icm_start_stop;&lt;br /&gt;
        articulated_part:             sw_icm_articulated_part;&lt;br /&gt;
        can_attach_wagon:             sw_icm_can_attach_wagon;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Language file so far ===&lt;br /&gt;
english.lng now contains this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap; max-height: 200px; overflow:scroll&amp;quot;&amp;gt;&lt;br /&gt;
##grflangid 0x01&lt;br /&gt;
&lt;br /&gt;
STR_GRF_NAME                 :NML Example NewGRF: Train&lt;br /&gt;
STR_GRF_DESC                 :{ORANGE}NML Example NewGRF: Train{}{BLACK}This NewGRF is intended to provide a coding example for the high-level NewGRF-coding language NML.{}Original graphics by {SILVER}Purno, {BLACK}coding by {SILVER}DJNekkid.{}{BLACK}This NewGRF defines a Dutch EMU, the ICM &#039;Koploper&#039;.&lt;br /&gt;
&lt;br /&gt;
STR_ICM_NAME                 :ICM &#039;Koploper&#039; (Electric)&lt;br /&gt;
STR_ICM_CANNOT_START         :... train too long (max. 4 coupled EMUs).&lt;br /&gt;
STR_ICM_CANNOT_ATTACH_OTHER  :... only other ICMs can be attached to ICM.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This is now a working 3-part EMU. In real life, the EMU is also available as a 4-part variant. In the next part of the tutorial, we will add the option to choose between a 3- and 4 part EMU via a refit.&lt;br /&gt;
&lt;br /&gt;
{{NMLTutorialNavbar|Train single engine|Train four part refit}}&lt;/div&gt;</summary>
		<author><name>Yexo</name></author>
	</entry>
	<entry>
		<id>https://www.tt-wiki.net/index.php?title=NMLTutorial/Tram_purchase_menu&amp;diff=7982</id>
		<title>NMLTutorial/Tram purchase menu</title>
		<link rel="alternate" type="text/html" href="https://www.tt-wiki.net/index.php?title=NMLTutorial/Tram_purchase_menu&amp;diff=7982"/>
		<updated>2011-12-13T22:28:02Z</updated>

		<summary type="html">&lt;p&gt;Yexo: /* The complete code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{NMLTutorial}}&lt;br /&gt;
&#039;&#039;The example used here is the HTM 4001 from the [http://dev.openttdcoop.org/projects/dutchtramset/repository Dutch Tram Set]. The original code and graphics for this are by FooBar. Code and graphics are both licensed according to the GPL v2 or later. The code has been modified for the purpose of this tutorial.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This continues and concludes the [[NMLTutorial/Tram graphics|third part]] of the tram example. We&#039;ll look into some things dealing with the purchase menu.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Purchase menu text ==&lt;br /&gt;
There is a callback that allows adding text to the purchase menu. In the Dutch Tram Set this is used to give you some information on how the vehicles were/are used in real life. For the tram in this example, we already defined such a text in the language files. Let&#039;s add it to the purchase menu.&lt;br /&gt;
&lt;br /&gt;
The callback needed for this you must again [http://newgrf-specs.tt-wiki.net/wiki/NML:Vehicles#Vehicle_callbacks look up] in the NML Documentation and is named &amp;lt;code&amp;gt;additional_text&amp;lt;/code&amp;gt;. And it&#039;s an easy one at that, because we can just return the string that must be displayed straight from the graphics block:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap;&amp;quot;&amp;gt;&lt;br /&gt;
    graphics {&lt;br /&gt;
        additional_text:         return string(STR_DESC_HTM_4001); //Additional text shown in purchase list&lt;br /&gt;
        articulated_part:        switch_articulated_htm_4001;&lt;br /&gt;
        shorten_vehicle:         switch_length_htm_4001;&lt;br /&gt;
        cargo_capacity:          switch_capacity_htm_4001;&lt;br /&gt;
        default:                 switch_spriteset_htm_4001;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Callback done. Easy!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Purchase menu sprite ==&lt;br /&gt;
You may remember a separate sprite and template for the purchase menu. In order to use this, you need a spriteset block and reference this from the graphics block. The spriteset is again pretty straightforward:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap;&amp;quot;&amp;gt;&lt;br /&gt;
spriteset(spriteset_purchase_htm_4001, &amp;quot;gfx/htm_4001.png&amp;quot;) {&lt;br /&gt;
    template_purchase(0, 140)&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Referencing that from the graphics block isn&#039;t too difficult either, as you&#039;ve done that before:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap;&amp;quot;&amp;gt;&lt;br /&gt;
    graphics {&lt;br /&gt;
        purchase:                spriteset_purchase_htm_4001; //Purchase menu sprite&lt;br /&gt;
        additional_text:         return string(STR_DESC_HTM_4001); //Additional text shown in purchase list&lt;br /&gt;
        articulated_part:        switch_articulated_htm_4001;&lt;br /&gt;
        shorten_vehicle:         switch_length_htm_4001;&lt;br /&gt;
        cargo_capacity:          switch_capacity_htm_4001;&lt;br /&gt;
        default:                 switch_spriteset_htm_4001;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The identifiers are of course the same in the graphics block and in the spriteset block. The spriteset block must be defined before the item block.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Fixing the purchase menu capacity display ==&lt;br /&gt;
Using the cargo capacity callback comes with a side-effect: the capacity display in the purchase menu is broken. The reason for this is that the &amp;lt;code&amp;gt;position_in_consist&amp;lt;/code&amp;gt; variable is [http://newgrf-specs.tt-wiki.net/wiki/NML:Vehicles#Vehicle_variables not available] in the purchase menu. As a result, the game can&#039;t calculate the capacity for each vehicle part in the purchase menu, you&#039;ll get some unknown behaviour and as a result an incorrect capacity in the purchase menu.&lt;br /&gt;
&lt;br /&gt;
The solution to this is to tell the game not to use the capacity from the callback in the purchase menu, but instead to use the capacity from the capacity property (form the property block) in the purchase menu.&lt;br /&gt;
&lt;br /&gt;
The way this solution works is to define a separate cargo capacity callback for the purchase menu, but instead of returning a capacity value linking this callback directly to the purchase menu spriteset. Sounds a bit of a trick solution, and it is. The result is that the cargo capacity callback for the purchase menu will fail and that the cargo capacity property is used instead. And above all it&#039;s not a hack, but completely legal NML code.&lt;br /&gt;
&lt;br /&gt;
The callback name for the graphics block to do this is called &amp;lt;code&amp;gt;purchase_cargo_capacity&amp;lt;/code&amp;gt; and can be found in the [http://newgrf-specs.tt-wiki.net/wiki/NML:Vehicles#Vehicle_callbacks usual place]. Your final graphics block will now look like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap;&amp;quot;&amp;gt;&lt;br /&gt;
    graphics {&lt;br /&gt;
        purchase:                spriteset_purchase_htm_4001; //Purchase menu sprite&lt;br /&gt;
        additional_text:         return string(STR_DESC_HTM_4001); //Additional text shown in purchase list&lt;br /&gt;
        articulated_part:        switch_articulated_htm_4001;&lt;br /&gt;
        shorten_vehicle:         switch_length_htm_4001;&lt;br /&gt;
        cargo_capacity:          switch_capacity_htm_4001;&lt;br /&gt;
        purchase_cargo_capacity: spriteset_purchase_htm_4001; //&amp;lt;-- linked to the purchase menu spriteset&lt;br /&gt;
        default:                 switch_spriteset_htm_4001;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The cargo capacity property will now be applied to each part of the vehicle for display in the purchase menu. In this case, three times the cargo capacity property will be displayed as total capacity in the purchase menu. And this completes the tram example.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== The complete code ==&lt;br /&gt;
The complete NML code for the tram vehicle:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap; max-height: 200px; overflow:scroll&amp;quot;&amp;gt;&lt;br /&gt;
// define the newgrf&lt;br /&gt;
grf {&lt;br /&gt;
	grfid:	&amp;quot;\FB\FB\01\02&amp;quot;;&lt;br /&gt;
	name:	string(STR_GRF_NAME);&lt;br /&gt;
	desc:	string(STR_GRF_DESCRIPTION);&lt;br /&gt;
	version:		REPO_REVISION;&lt;br /&gt;
	min_compatible_version:	87;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////&lt;br /&gt;
//Purchase menu sprite//&lt;br /&gt;
////////////////////////&lt;br /&gt;
&lt;br /&gt;
spriteset(spriteset_purchase_htm_4001, &amp;quot;gfx/htm_4001.png&amp;quot;) {&lt;br /&gt;
    template_purchase(0, 140)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////&lt;br /&gt;
//Vehicle sprites//&lt;br /&gt;
///////////////////&lt;br /&gt;
&lt;br /&gt;
spriteset(spriteset_real_htm_4001, &amp;quot;gfx/htm_4001.png&amp;quot;) {&lt;br /&gt;
    template_tram_28(0, 20)&lt;br /&gt;
}&lt;br /&gt;
spriteset(spriteset_real_htm_4001_1, &amp;quot;gfx/htm_4001.png&amp;quot;) {&lt;br /&gt;
    template_tram_24(0, 60)&lt;br /&gt;
}&lt;br /&gt;
spriteset(spriteset_real_htm_4001_2, &amp;quot;gfx/htm_4001.png&amp;quot;) {&lt;br /&gt;
    template_tram_28(0, 100)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
switch (FEAT_ROADVEHS, SELF, switch_spriteset_htm_4001, position_in_consist ) {&lt;br /&gt;
    1: spriteset_real_htm_4001_1;&lt;br /&gt;
    2: spriteset_real_htm_4001_2;&lt;br /&gt;
    spriteset_real_htm_4001; //default&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////&lt;br /&gt;
//vehicle callbacks//&lt;br /&gt;
/////////////////////&lt;br /&gt;
&lt;br /&gt;
//set number of articulated parts&lt;br /&gt;
switch (FEAT_ROADVEHS, SELF, switch_articulated_htm_4001, extra_callback_info1) {&lt;br /&gt;
    1..2: return item_tram_htm_4001; //use same vehicle for all parts&lt;br /&gt;
    return CB_RESULT_NO_MORE_ARTICULATED_PARTS; //stop adding vehicle parts&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//set length of each part&lt;br /&gt;
switch (FEAT_ROADVEHS, SELF, switch_length_htm_4001, position_in_consist ) {&lt;br /&gt;
    1: return 2;&lt;br /&gt;
    return 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//set capacity of each part&lt;br /&gt;
switch (FEAT_ROADVEHS, SELF, switch_capacity_htm_4001, position_in_consist ) {&lt;br /&gt;
    1: return 26;&lt;br /&gt;
    return 38; //default&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////&lt;br /&gt;
//vehicle properties//&lt;br /&gt;
//////////////////////&lt;br /&gt;
&lt;br /&gt;
item (FEAT_ROADVEHS, item_tram_htm_4001) {&lt;br /&gt;
    property {&lt;br /&gt;
        name:                        string(STR_NAME_HTM_4001);&lt;br /&gt;
        introduction_date:           date(2006,1,1);&lt;br /&gt;
        model_life:                  VEHICLE_NEVER_EXPIRES;&lt;br /&gt;
        retire_early:                0;&lt;br /&gt;
        vehicle_life:                25;&lt;br /&gt;
        loading_speed:               25;&lt;br /&gt;
        cost_factor:                 224;&lt;br /&gt;
        running_cost_factor:         112;&lt;br /&gt;
        speed:                       81 km/h;&lt;br /&gt;
        power:                       966 hp;&lt;br /&gt;
        weight:                      58 ton;&lt;br /&gt;
        cargo_capacity:              (38*2+26)/3;&lt;br /&gt;
        tractive_effort_coefficient: 0.5;&lt;br /&gt;
        air_drag_coefficient:        0;&lt;br /&gt;
        //sound_effect:              no sound&lt;br /&gt;
        //visual_effect:             use default (none)&lt;br /&gt;
        &lt;br /&gt;
        //callback_flags:            no need to set this&lt;br /&gt;
        reliability_decay:           20;&lt;br /&gt;
        climates_available:          ALL_CLIMATES;&lt;br /&gt;
        refittable_cargo_classes:    bitmask(CC_PASSENGERS);&lt;br /&gt;
        sprite_id:                   SPRITE_ID_NEW_ROADVEH; //use custom sprites&lt;br /&gt;
        misc_flags:                  bitmask(ROADVEH_FLAG_TRAM); //make this a tram&lt;br /&gt;
        refit_cost:                  0; //refits are free&lt;br /&gt;
        running_cost_base:           RUNNING_COST_ROADVEH;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    graphics {&lt;br /&gt;
        purchase:                spriteset_purchase_htm_4001; //Purchase menu sprite&lt;br /&gt;
        additional_text:         return string(STR_DESC_HTM_4001); //Additional text shown in purchase list&lt;br /&gt;
        articulated_part:        switch_articulated_htm_4001;&lt;br /&gt;
        shorten_vehicle:         switch_length_htm_4001;&lt;br /&gt;
        cargo_capacity:          switch_capacity_htm_4001;&lt;br /&gt;
        purchase_cargo_capacity: spriteset_purchase_htm_4001;&lt;br /&gt;
        default:                 switch_spriteset_htm_4001;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
That concludes the articulated tram example. The next part of this tutorial will a train example with some fancy features.&lt;br /&gt;
&lt;br /&gt;
{{NMLTutorialNavbar|Tram graphics|Train}}&lt;/div&gt;</summary>
		<author><name>Yexo</name></author>
	</entry>
	<entry>
		<id>https://www.tt-wiki.net/index.php?title=NMLTutorial/Tram_graphics&amp;diff=7981</id>
		<title>NMLTutorial/Tram graphics</title>
		<link rel="alternate" type="text/html" href="https://www.tt-wiki.net/index.php?title=NMLTutorial/Tram_graphics&amp;diff=7981"/>
		<updated>2011-12-13T22:27:41Z</updated>

		<summary type="html">&lt;p&gt;Yexo: /* Total code so far */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{NMLTutorial}}&lt;br /&gt;
&#039;&#039;The example used here is the HTM 4001 from the [http://dev.openttdcoop.org/projects/dutchtramset/repository Dutch Tram Set]. The original code and graphics for this are by FooBar. Code and graphics are both licensed according to the GPL v2 or later. The code has been modified for the purpose of this tutorial.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This continues the [[NMLTutorial/Tram articulation|second part]] of the tram example. Now graphics will be added to the tram.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== The graphics ==&lt;br /&gt;
As this tutorial is about coding NML and not about drawing graphics, we&#039;ll give you the graphics for free:&lt;br /&gt;
&lt;br /&gt;
[[Image:Htm 4001.png|frame|none|Graphics for each part of the HTM 4001. Drawn by FooBar.]]&lt;br /&gt;
&lt;br /&gt;
=== Templates ===&lt;br /&gt;
The graphics in this file are templated (and actually use the templates used as example for the template chapter of this tutorial). That means we&#039;ll be using templates here as well. Check [[NMLTutorial/Template|back]] if you don&#039;t remember how to do that. These are the templates you should end up with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap;&amp;quot;&amp;gt;&lt;br /&gt;
template template_tram_28(x, y) {&lt;br /&gt;
    //[left_x,  upper_y,    width,     height,     offset_x,     offset_y]&lt;br /&gt;
    [x,         y,          10,        28,           -4,         -11]&lt;br /&gt;
    [x+ 20,     y,          26,        28,          -17,         -14]&lt;br /&gt;
    [x+ 50,     y,          36,        28,          -20,         -20]&lt;br /&gt;
    [x+ 90,     y,          26,        28,           -9,         -15]&lt;br /&gt;
    [x+120,     y,          10,        28,           -4,         -13]&lt;br /&gt;
    [x+140,     y,          26,        28,          -16,         -16]&lt;br /&gt;
    [x+170,     y,          36,        28,          -16,         -20]&lt;br /&gt;
    [x+210,     y,          26,        28,           -8,         -16]&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
template template_tram_24(x, y) {&lt;br /&gt;
    //[left_x,  upper_y,    width,     height,     offset_x,     offset_y]&lt;br /&gt;
    [x,         y,          10,        28,           -4,         -11]&lt;br /&gt;
    [x+ 20,     y,          26,        28,          -17,         -14]&lt;br /&gt;
    [x+ 50,     y,          36,        28,          -22,         -20]&lt;br /&gt;
    [x+ 90,     y,          26,        28,           -9,         -15]&lt;br /&gt;
    [x+120,     y,          10,        28,           -4,         -15]&lt;br /&gt;
    [x+140,     y,          26,        28,          -16,         -16]&lt;br /&gt;
    [x+170,     y,          36,        28,          -14,         -20]&lt;br /&gt;
    [x+210,     y,          26,        28,           -8,         -16]&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
template template_purchase(x, y) {&lt;br /&gt;
    //[left_x,  upper_y,    width,     height,     offset_x,     offset_y]&lt;br /&gt;
    [x,         y,          50,        12,          -25,          -6]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The purchase menu sprite will be added on the next page, but it doesn&#039;t hurt to have the template defined now. Every template has arguments for the position of the top left sprite corner.&lt;br /&gt;
&lt;br /&gt;
=== Spritesets ===&lt;br /&gt;
With these templates, we can make three spritesets for the three vehicle parts. We give the spritesets proper names and include a reference to the image file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap;&amp;quot;&amp;gt;&lt;br /&gt;
spriteset(spriteset_real_htm_4001, &amp;quot;gfx/htm_4001.png&amp;quot;) {&lt;br /&gt;
    template_tram_28(0, 20)&lt;br /&gt;
}&lt;br /&gt;
spriteset(spriteset_real_htm_4001_1, &amp;quot;gfx/htm_4001.png&amp;quot;) {&lt;br /&gt;
    template_tram_24(0, 60)&lt;br /&gt;
}&lt;br /&gt;
spriteset(spriteset_real_htm_4001_2, &amp;quot;gfx/htm_4001.png&amp;quot;) {&lt;br /&gt;
    template_tram_28(0, 100)&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice that the first and last vehicle part are 28 px long and use the 28 px template. The middle part is only 24 px long and uses the 24 px template.&lt;br /&gt;
&lt;br /&gt;
Because there are no different sprites for &amp;quot;empty&amp;quot;, &amp;quot;full&amp;quot;, &amp;quot;loaded&amp;quot; and &amp;quot;loading&amp;quot;, we don&#039;t have to define a spritegroup in this case. If you had different sprites for these different states, you would need to combine them in a spritegroup first.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Attaching the graphics with a switch block ==&lt;br /&gt;
From the graphics block we will use the &#039;&#039;default&#039;&#039; callback to reference the spritesets. However, because we can reference only one spriteset (or -group) from the graphics block, we need an intermediate switch block to decide the graphics depending on the position in the vehicle.&lt;br /&gt;
&lt;br /&gt;
So from the graphics block we reference a switch block for the default graphics:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap;&amp;quot;&amp;gt;&lt;br /&gt;
    graphics {&lt;br /&gt;
        articulated_part:        switch_articulated_htm_4001;&lt;br /&gt;
        cargo_capacity:          switch_capacity_htm_4001;&lt;br /&gt;
        default:                 switch_spriteset_htm_4001;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This then links to a switch block. The workings of this switch block will be similar to that of the cargo capacity callback, making a decicion based on the &amp;lt;code&amp;gt;position_in_consist&amp;lt;/code&amp;gt; [http://newgrf-specs.tt-wiki.net/wiki/NML:Vehicles#Vehicle_variables variable]. However, this time we need three separate ranges (because three different spritesets) and we mustn&#039;t return a value but now reference these spritesets:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap;&amp;quot;&amp;gt;&lt;br /&gt;
switch (FEAT_ROADVEHS, SELF, switch_spriteset_htm_4001, position_in_consist ) {&lt;br /&gt;
    1: spriteset_real_htm_4001_1;&lt;br /&gt;
    2: spriteset_real_htm_4001_2;&lt;br /&gt;
    spriteset_real_htm_4001; //default&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So for the second vehicle part (with index 1 in &amp;lt;code&amp;gt;position_in_consist&amp;lt;/code&amp;gt;) we use the graphics of the &#039;spriteset_real_htm_4001_1&#039; spriteset block. For the last part (index 2) we use the &#039;&#039;spriteset_real_htm_4001_2&#039;&#039; spriteset. For all other parts (in this case only the first) we&#039;ll default to the &#039;&#039;spriteset_real_htm_4001&#039;&#039; spriteset.&lt;br /&gt;
&lt;br /&gt;
This has the graphics sorted and you can encode the NewGRF to see the result ingame.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Shorten vehicle callback ==&lt;br /&gt;
If you did encode the previous results, you&#039;ll notice that the individual vehicle parts are very far apart. This is because we used shorter sprites than the 32px default length. We&#039;ll need to tell the game that our vehicle parts are shorter!&lt;br /&gt;
&lt;br /&gt;
This is done by means of the shorten vehicle callback, incidentally named &amp;lt;code&amp;gt;shorten_vehicle&amp;lt;/code&amp;gt; for use in the graphics block, look it up [http://newgrf-specs.tt-wiki.net/wiki/NML:Vehicles#Vehicle_callbacks here]. Because different parts have different lengths, we once more can&#039;t just return a value from the graphics block but need an intermediate switch block:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap;&amp;quot;&amp;gt;&lt;br /&gt;
    graphics {&lt;br /&gt;
        articulated_part:        switch_articulated_htm_4001;&lt;br /&gt;
        shorten_vehicle:         switch_length_htm_4001; //&amp;lt;-- this one is added now&lt;br /&gt;
        cargo_capacity:          switch_capacity_htm_4001;&lt;br /&gt;
        default:                 switch_spriteset_htm_4001;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The switch block itself will once more make a decision based on the &amp;lt;code&amp;gt;position_in_consist&amp;lt;/code&amp;gt; variable. The value to return for the callback is how many times 12,5% (1/8) to reduce the vehicle length with. The first and last part of the vehicle are 28px, which is (1/8) shorter than 32px, so the return value here is 1. The middle part is 24px, which is (2/8) shorter so the return value for this part is 2. The switch block:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap;&amp;quot;&amp;gt;&lt;br /&gt;
switch (FEAT_ROADVEHS, SELF, switch_length_htm_4001, position_in_consist ) {&lt;br /&gt;
    1: return 2;&lt;br /&gt;
    return 1;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The second vehicle part (with index 1 in &amp;lt;code&amp;gt;position_in_consist&amp;lt;/code&amp;gt;) returns value 2 and value 1 is returned for all other positions (the first and last part of the vehicle). Once more notice that the identifier of the switch block is the same as that used in the graphics block.&lt;br /&gt;
&lt;br /&gt;
This should fix our vehicle and now the parts actually appear connected.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Total code so far ==&lt;br /&gt;
If you put everything in the correct order, you should have this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap; max-height: 200px; overflow:scroll&amp;quot;&amp;gt;&lt;br /&gt;
// define the newgrf&lt;br /&gt;
grf {&lt;br /&gt;
	grfid:	&amp;quot;\FB\FB\01\02&amp;quot;;&lt;br /&gt;
	name:	string(STR_GRF_NAME);&lt;br /&gt;
	desc:	string(STR_GRF_DESCRIPTION);&lt;br /&gt;
	version:		REPO_REVISION;&lt;br /&gt;
	min_compatible_version:	87;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////&lt;br /&gt;
//Vehicle sprites//&lt;br /&gt;
///////////////////&lt;br /&gt;
&lt;br /&gt;
spriteset(spriteset_real_htm_4001, &amp;quot;gfx/htm_4001.png&amp;quot;) {&lt;br /&gt;
    template_tram_28(0, 20)&lt;br /&gt;
}&lt;br /&gt;
spriteset(spriteset_real_htm_4001_1, &amp;quot;gfx/htm_4001.png&amp;quot;) {&lt;br /&gt;
    template_tram_24(0, 60)&lt;br /&gt;
}&lt;br /&gt;
spriteset(spriteset_real_htm_4001_2, &amp;quot;gfx/htm_4001.png&amp;quot;) {&lt;br /&gt;
    template_tram_28(0, 100)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
switch (FEAT_ROADVEHS, SELF, switch_spriteset_htm_4001, position_in_consist ) {&lt;br /&gt;
    1: spriteset_real_htm_4001_1;&lt;br /&gt;
    2: spriteset_real_htm_4001_2;&lt;br /&gt;
    spriteset_real_htm_4001; //default&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////&lt;br /&gt;
//vehicle callbacks//&lt;br /&gt;
/////////////////////&lt;br /&gt;
&lt;br /&gt;
//set number of articulated parts&lt;br /&gt;
switch (FEAT_ROADVEHS, SELF, switch_articulated_htm_4001, extra_callback_info1) {&lt;br /&gt;
    1..2: return item_tram_htm_4001; //use same vehicle for all parts&lt;br /&gt;
    return CB_RESULT_NO_MORE_ARTICULATED_PARTS; //stop adding vehicle parts&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//set length of each part&lt;br /&gt;
switch (FEAT_ROADVEHS, SELF, switch_length_htm_4001, position_in_consist ) {&lt;br /&gt;
    1: return 2;&lt;br /&gt;
    return 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//set capacity of each part&lt;br /&gt;
switch (FEAT_ROADVEHS, SELF, switch_capacity_htm_4001, position_in_consist ) {&lt;br /&gt;
    1: return 26;&lt;br /&gt;
    return 38; //default&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////&lt;br /&gt;
//vehicle properties//&lt;br /&gt;
//////////////////////&lt;br /&gt;
&lt;br /&gt;
item (FEAT_ROADVEHS, item_tram_htm_4001) {&lt;br /&gt;
    property {&lt;br /&gt;
        name:                        string(STR_NAME_HTM_4001);&lt;br /&gt;
        introduction_date:           date(2006,1,1);&lt;br /&gt;
        model_life:                  VEHICLE_NEVER_EXPIRES;&lt;br /&gt;
        retire_early:                0;&lt;br /&gt;
        vehicle_life:                25;&lt;br /&gt;
        loading_speed:               25;&lt;br /&gt;
        cost_factor:                 224;&lt;br /&gt;
        running_cost_factor:         112;&lt;br /&gt;
        speed:                       81 km/h;&lt;br /&gt;
        power:                       966 hp;&lt;br /&gt;
        weight:                      58 ton;&lt;br /&gt;
        cargo_capacity:              (38*2+26)/3;&lt;br /&gt;
        tractive_effort_coefficient: 0.5;&lt;br /&gt;
        air_drag_coefficient:        0;&lt;br /&gt;
        //sound_effect:              no sound&lt;br /&gt;
        //visual_effect:             use default (none)&lt;br /&gt;
        &lt;br /&gt;
        //callback_flags:            no need to set this&lt;br /&gt;
        reliability_decay:           20;&lt;br /&gt;
        climates_available:          ALL_CLIMATES;&lt;br /&gt;
        refittable_cargo_classes:    bitmask(CC_PASSENGERS);&lt;br /&gt;
        sprite_id:                   SPRITE_ID_NEW_ROADVEH; //use custom sprites&lt;br /&gt;
        misc_flags:                  bitmask(ROADVEH_FLAG_TRAM); //make this a tram&lt;br /&gt;
        refit_cost:                  0; //refits are free&lt;br /&gt;
        running_cost_base:           RUNNING_COST_ROADVEH;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    graphics {&lt;br /&gt;
        articulated_part:        switch_articulated_htm_4001;&lt;br /&gt;
        shorten_vehicle:         switch_length_htm_4001; //&amp;lt;-- this one is added now&lt;br /&gt;
        cargo_capacity:          switch_capacity_htm_4001;&lt;br /&gt;
        default:                 switch_spriteset_htm_4001;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The graphics are there, the tram seems complete. Or is it? There still is a sprite for the purchase menu left and if you&#039;ll look closely you&#039;ll notice that the capacity displayed in the purchase menu isn&#039;t correct. And remember the text we added to the language file to be displayed in the purchase menu? That&#039;s all next, in the last part of this tram example.&lt;br /&gt;
&lt;br /&gt;
{{NMLTutorialNavbar|Tram articulation|Tram purchase menu}}&lt;/div&gt;</summary>
		<author><name>Yexo</name></author>
	</entry>
	<entry>
		<id>https://www.tt-wiki.net/index.php?title=NMLTutorial/Tram_articulation&amp;diff=7980</id>
		<title>NMLTutorial/Tram articulation</title>
		<link rel="alternate" type="text/html" href="https://www.tt-wiki.net/index.php?title=NMLTutorial/Tram_articulation&amp;diff=7980"/>
		<updated>2011-12-13T22:27:12Z</updated>

		<summary type="html">&lt;p&gt;Yexo: Use CB_RESULT_NO_MORE_ARTICULATED_PARTS instead of hardcodec 0xFF&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{NMLTutorial}}&lt;br /&gt;
&#039;&#039;The example used here is the HTM 4001 from the [http://dev.openttdcoop.org/projects/dutchtramset/repository Dutch Tram Set]. The original code and graphics for this are by FooBar. Code and graphics are both licensed according to the GPL v2 or later. The code has been modified for the purpose of this tutorial.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This continues the [[NMLTutorial/Tram|first part]] of the tram example. Here we&#039;ll define the tram&#039;s item block and make it articulated.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Item block ==&lt;br /&gt;
The item block is not that different from that of a regular road vehicle. A tram is still a road vehicle, so the [http://newgrf-specs.tt-wiki.net/wiki/NML:Features feature] will again be &amp;lt;code&amp;gt;FEAT_ROADVEHS&amp;lt;/code&amp;gt;. Give the item an identifier (here &#039;&#039;item_tram_htm_4001&#039;&#039;), add a property sub-block and fill it like you did with the road vehicle.&lt;br /&gt;
&lt;br /&gt;
One important thing to know is that the &amp;lt;code&amp;gt;cargo_capacity&amp;lt;/code&amp;gt; property applies to a single part of the articulated vehicle. So the total capacity will be that what you have set for &amp;lt;code&amp;gt;cargo_capacity&amp;lt;/code&amp;gt; multiplied by the number of vehicle parts. This means that the capacity can only be a multiple of the number of vehicle parts. The other properties apply to the vehicle as a whole.&lt;br /&gt;
&lt;br /&gt;
Again you need to look all the available properties up in the [http://newgrf-specs.tt-wiki.net/wiki/NML:Properties_and_variables_and_callbacks NML Documentation] and whey you do you may arrive at an item block something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
item (FEAT_ROADVEHS, item_tram_htm_4001) {&lt;br /&gt;
    property {&lt;br /&gt;
        name:                        string(STR_NAME_HTM_4001);&lt;br /&gt;
        introduction_date:           date(2006,1,1);&lt;br /&gt;
        model_life:                  VEHICLE_NEVER_EXPIRES;&lt;br /&gt;
        retire_early:                0;&lt;br /&gt;
        vehicle_life:                25;&lt;br /&gt;
        loading_speed:               25;&lt;br /&gt;
        cost_factor:                 224;&lt;br /&gt;
        running_cost_factor:         112;&lt;br /&gt;
        speed:                       81 km/h;&lt;br /&gt;
        power:                       966 hp;&lt;br /&gt;
        weight:                      58 ton;&lt;br /&gt;
        cargo_capacity:              (38*2+26)/3;&lt;br /&gt;
        tractive_effort_coefficient: 0.5;&lt;br /&gt;
        air_drag_coefficient:        0;&lt;br /&gt;
        //sound_effect:              no sound&lt;br /&gt;
        //visual_effect:             use default (none)&lt;br /&gt;
        &lt;br /&gt;
        //callback_flags:            no need to set this&lt;br /&gt;
        reliability_decay:           20;&lt;br /&gt;
        climates_available:          ALL_CLIMATES;&lt;br /&gt;
        refittable_cargo_classes:    bitmask(CC_PASSENGERS);&lt;br /&gt;
        sprite_id:                   SPRITE_ID_NEW_ROADVEH; //use custom sprites&lt;br /&gt;
        misc_flags:                  bitmask(ROADVEH_FLAG_TRAM); //make this a tram&lt;br /&gt;
        refit_cost:                  0; //refits are free&lt;br /&gt;
        running_cost_base:           RUNNING_COST_ROADVEH;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    graphics {&lt;br /&gt;
        //this will be added next&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Adding callbacks ==&lt;br /&gt;
As you may have guessed, making the vehicle articulated has something to do with callbacks. These will be referenced from the graphics block within the item block. We&#039;ll also be adding a second callback that makes the capacity different for each vehicle part. The middle part of the vehicle (as you will see on the next page) is somewhat shorter and thus can carry less passengers. We can show this in the vehicle details window using a callback.&lt;br /&gt;
&lt;br /&gt;
=== Articulated vehicle callback ===&lt;br /&gt;
The name of the acticulated vehicle callback that must be used in the graphics block is &amp;lt;code&amp;gt;articulated_part&amp;lt;/code&amp;gt;, which you can find in [http://newgrf-specs.tt-wiki.net/wiki/NML:Vehicles#Vehicle_callbacks this table]. There you&#039;ll also find information on how to use this callback.&lt;br /&gt;
&lt;br /&gt;
Because this callback is a little more advanced than just telling how many vehicle parts you want, you need a switch with this callback to be able to use it. This means that from the graphics block you need to reference a switch block:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
    graphics {&lt;br /&gt;
        articulated_part:        switch_articulated_htm_4001;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
How this callback works is that the game runs the switch referenced in the graphics block multiple times. Every time the switch is run, it will increase the variable &amp;lt;code&amp;gt;extra_callback_info1&amp;lt;/code&amp;gt; with 1, starting at 1. And every time the switch must return the identifier of a vehicle item that must be added. This can be the identifier of the item you define the callback for, or a different vehicle item. Because you can change the looks and properties of the attached vehicle parts by means of other switches/callbacks, it is fine to return the identifier of the same vehicle. If you want the game to stop adding more parts to the vehicle, you have the switch return a value of CB_RESULT_NO_MORE_ARTICULATED_PARTS.&lt;br /&gt;
&lt;br /&gt;
This is a lot in words, but not so much in code. The switch you need is this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
switch (FEAT_ROADVEHS, SELF, switch_articulated_htm_4001, extra_callback_info1) {&lt;br /&gt;
    1..2: return item_tram_htm_4001; //use same vehicle for all parts&lt;br /&gt;
    return CB_RESULT_NO_MORE_ARTICULATED_PARTS; //stop adding vehicle parts&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that the identifier used here is the same as the one in the graphics block. So the first time the switch is run, the value of &amp;lt;code&amp;gt;extra_callback_info1&amp;lt;/code&amp;gt; will be one. For value 1, &amp;lt;code&amp;gt;item_tram_htm_4001&amp;lt;/code&amp;gt; is returned as vehicle identifier for the part to add to this vehicle. Then the switch is run again, now with &amp;lt;code&amp;gt;extra_callback_info1&amp;lt;/code&amp;gt; set to 2. Again vehicle identifier &amp;lt;code&amp;gt;item_tram_htm_4001&amp;lt;/code&amp;gt; is returned and another vehicle part added. Then the switch is run again with &amp;lt;code&amp;gt;extra_callback_info1&amp;lt;/code&amp;gt; set to 3. This time the switch will return 0xFF, the game will add no new part and will stop running this switch.&lt;br /&gt;
&lt;br /&gt;
Of course, this switch block goes above the item block, as it needs to be defined before you can use it. This particular code will now build a three part articulated vehicle.&lt;br /&gt;
&lt;br /&gt;
=== Cargo capacity callback ===&lt;br /&gt;
A different callback can set the capacity of each of these three parts. This is useful if you want different capacities for each part (if each part must have the same capacity, the cargo_capacity property is enough and you don&#039;t need this callback).&lt;br /&gt;
&lt;br /&gt;
The name of this callback for the graphics block is &amp;lt;code&amp;gt;cargo_capacity&amp;lt;/code&amp;gt; and you can look that up in the [http://newgrf-specs.tt-wiki.net/wiki/NML:Vehicles#Vehicle_callbacks same place] as where you found the articulated vehicle callback. You can directly return a value for this callback from the graphics block, but then this would be the same for each part and that kinda defeats the purpose of this callback. So we&#039;ll have to use a switch block here as well, referred to from the graphics block:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
    graphics {&lt;br /&gt;
        articulated_part:        switch_articulated_htm_4001;&lt;br /&gt;
        cargo_capacity:          switch_capacity_htm_4001;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In order to return a different value for each vehicle part, we somehow need to use the switch block to make a decision based on the position in the vehicle. Luckily, there&#039;s a variable that does just that: it is called &amp;lt;code&amp;gt;position_in_consist&amp;lt;/code&amp;gt; and you can find it [http://newgrf-specs.tt-wiki.net/wiki/NML:Vehicles#Vehicle_variables here] in the NML Documentation.&lt;br /&gt;
&lt;br /&gt;
For each vehicle part the game will tell the switch of what vehicle part number it wants to know the capacity. The switch must then return this value. In code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
switch (FEAT_ROADVEHS, SELF, switch_capacity_htm_4001, position_in_consist ) {&lt;br /&gt;
    1: return 26;&lt;br /&gt;
    return 38; //default&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Also here the identifier of the switch is the same as the one used in the graphics block. For &amp;lt;code&amp;gt;position_in_consist&amp;lt;/code&amp;gt; 1 (the second vehicle part) this switch will return a capacity of 26. For all other vehicle parts (in this case only the first and the last, as we have a three part vehicle) it will return the default value of 38.&lt;br /&gt;
&lt;br /&gt;
Also this switch block goes above the item block.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Total code so far ==&lt;br /&gt;
If you put everything in the correct order, you should now have this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap; max-height: 200px; overflow:scroll&amp;quot;&amp;gt;&lt;br /&gt;
// define the newgrf&lt;br /&gt;
grf {&lt;br /&gt;
	grfid:	&amp;quot;\FB\FB\01\02&amp;quot;;&lt;br /&gt;
	name:	string(STR_GRF_NAME);&lt;br /&gt;
	desc:	string(STR_GRF_DESCRIPTION);&lt;br /&gt;
	version:		REPO_REVISION;&lt;br /&gt;
	min_compatible_version:	87;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////&lt;br /&gt;
//vehicle callbacks//&lt;br /&gt;
/////////////////////&lt;br /&gt;
&lt;br /&gt;
//set number of articulated parts&lt;br /&gt;
switch (FEAT_ROADVEHS, SELF, switch_articulated_htm_4001, extra_callback_info1) {&lt;br /&gt;
    1..2: return item_tram_htm_4001; //use same vehicle for all parts&lt;br /&gt;
    return CB_RESULT_NO_MORE_ARTICULATED_PARTS; //stop adding vehicle parts&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//set capacity of each part&lt;br /&gt;
switch (FEAT_ROADVEHS, SELF, switch_capacity_htm_4001, position_in_consist ) {&lt;br /&gt;
    1: return 26;&lt;br /&gt;
    return 38; //default&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////&lt;br /&gt;
//vehicle properties//&lt;br /&gt;
//////////////////////&lt;br /&gt;
&lt;br /&gt;
item (FEAT_ROADVEHS, item_tram_htm_4001) {&lt;br /&gt;
    property {&lt;br /&gt;
        name:                        string(STR_NAME_HTM_4001);&lt;br /&gt;
        introduction_date:           date(2006,1,1);&lt;br /&gt;
        model_life:                  VEHICLE_NEVER_EXPIRES;&lt;br /&gt;
        retire_early:                0;&lt;br /&gt;
        vehicle_life:                25;&lt;br /&gt;
        loading_speed:               25;&lt;br /&gt;
        cost_factor:                 224;&lt;br /&gt;
        running_cost_factor:         112;&lt;br /&gt;
        speed:                       81 km/h;&lt;br /&gt;
        power:                       966 hp;&lt;br /&gt;
        weight:                      58 ton;&lt;br /&gt;
        cargo_capacity:              (38*2+26)/3;&lt;br /&gt;
        tractive_effort_coefficient: 0.5;&lt;br /&gt;
        air_drag_coefficient:        0;&lt;br /&gt;
        //sound_effect:              no sound&lt;br /&gt;
        //visual_effect:             use default (none)&lt;br /&gt;
        &lt;br /&gt;
        //callback_flags:            no need to set this&lt;br /&gt;
        reliability_decay:           20;&lt;br /&gt;
        climates_available:          ALL_CLIMATES;&lt;br /&gt;
        refittable_cargo_classes:    bitmask(CC_PASSENGERS);&lt;br /&gt;
        sprite_id:                   SPRITE_ID_NEW_ROADVEH; //use custom sprites&lt;br /&gt;
        misc_flags:                  bitmask(ROADVEH_FLAG_TRAM); //make this a tram&lt;br /&gt;
        refit_cost:                  0; //refits are free&lt;br /&gt;
        running_cost_base:           RUNNING_COST_ROADVEH;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    graphics {&lt;br /&gt;
        articulated_part:        switch_articulated_htm_4001;&lt;br /&gt;
        cargo_capacity:          switch_capacity_htm_4001;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Because we haven&#039;t added graphics, you cannot compile this into a NewGRF just yet. So we&#039;ll look into the graphics next.&lt;br /&gt;
&lt;br /&gt;
{{NMLTutorialNavbar|Tram|Tram graphics}}&lt;/div&gt;</summary>
		<author><name>Yexo</name></author>
	</entry>
	<entry>
		<id>https://www.tt-wiki.net/index.php?title=NMLTutorial/Object&amp;diff=7715</id>
		<title>NMLTutorial/Object</title>
		<link rel="alternate" type="text/html" href="https://www.tt-wiki.net/index.php?title=NMLTutorial/Object&amp;diff=7715"/>
		<updated>2011-08-27T22:05:16Z</updated>

		<summary type="html">&lt;p&gt;Yexo: use consistent naming throughout tutorial&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{NMLTutorial}}&lt;br /&gt;
&#039;&#039;The example used here is from the [http://dev.openttdcoop.org/projects/dutchroadfurniture/repository Dutch Road Furniture]. The original graphics for this are by FooBar. The code is by FooBar, based on code for the object example from the [http://dev.openttdcoop.org/projects/nml/repository/show/examples NML source] by planetmaker and Hirundu. Code and graphics are both licensed according to the GPL v2 or later. The code has been modified for the purpose of this tutorial.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
Objects, as well as stations, houses, industry tiles and airport tiles are coded slightly differently than vehicles. This difference mainly has to do with how sprites are defined. Item blocks and callbacks with switch blocks are still used as before, so our focus will be mainly on the graphics part. Stations are currently not yet possible in NML.&lt;br /&gt;
&lt;br /&gt;
In this example we will make an object with four views to be used on flat ground tiles. After that we&#039;ll also make this object work on slopes, using some advanced features available in OpenTTD.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Folder structure ==&lt;br /&gt;
For this example we&#039;ll assume the following folder structure. There will be one language file in the &#039;&#039;lang&#039;&#039; folder, one graphics file in the &#039;&#039;gfx&#039;&#039; folder. These two folders sit together with the main NML file in one project folder:&lt;br /&gt;
&lt;br /&gt;
 object_example&lt;br /&gt;
  |- lang&lt;br /&gt;
  |   |- english.lng&lt;br /&gt;
  |- gfx&lt;br /&gt;
  |   |- dutch_fingerpost.png&lt;br /&gt;
  |- custom_tags.txt&lt;br /&gt;
  |- example_object.nml&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== NML file ==&lt;br /&gt;
Start the NML file by adding a grf block.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
grf {&lt;br /&gt;
    grfid:                  &amp;quot;\FB\FB\05\01&amp;quot;;&lt;br /&gt;
    name:                   string(STR_GRF_NAME);&lt;br /&gt;
    desc:                   string(STR_GRF_DESCRIPTION);&lt;br /&gt;
    version:                0;&lt;br /&gt;
    min_compatible_version: 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nothing fancy there, just like we used to do and starting at version 0.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Item definition and property block ==&lt;br /&gt;
The item block for an object looks very similar to that of a vehicle. Of course now you use &amp;lt;code&amp;gt;FEAT_OBJECTS&amp;lt;/code&amp;gt; as [http://newgrf-specs.tt-wiki.net/wiki/NML:Features feature] and give it an identifier of your choice. In the item block you add a property block listing the [http://newgrf-specs.tt-wiki.net/wiki/NML:Objects#Object_properties properties for the object] and a graphics block:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
item (FEAT_OBJECTS, item_fingerpost_3) {&lt;br /&gt;
    property {&lt;br /&gt;
        class:                  &amp;quot;NLRF&amp;quot;;&lt;br /&gt;
        classname:              string(STR_NLRF);&lt;br /&gt;
        name:                   string(STR_FINGERPOST_3);&lt;br /&gt;
        climates_available:     ALL_CLIMATES;&lt;br /&gt;
        size:                   [1,1];&lt;br /&gt;
        build_cost_multiplier:  2;&lt;br /&gt;
        remove_cost_multiplier: 8;&lt;br /&gt;
        introduction_date:      date(1961,1,1);&lt;br /&gt;
        end_of_life_date:       0xFFFFFFFF;&lt;br /&gt;
        object_flags:           bitmask(OBJ_FLAG_REMOVE_IS_INCOME, OBJ_FLAG_NO_FOUNDATIONS, OBJ_FLAG_ALLOW_BRIDGE);&lt;br /&gt;
        height:                 2;&lt;br /&gt;
        num_views:              4;&lt;br /&gt;
    }&lt;br /&gt;
    graphics {&lt;br /&gt;
        additional_text:    string(STR_FINGERPOST_3_PURCHASE);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== property block ===&lt;br /&gt;
Some properties may need a little explaining; others should be self-explanatory or check the [http://newgrf-specs.tt-wiki.net/wiki/NML:Objects#Object_properties NML Documentation] for details.&lt;br /&gt;
&lt;br /&gt;
; class&lt;br /&gt;
: A four character string using only capital letters and numbers. This defines in what &amp;quot;group&amp;quot; this object is added in the object construction window. If you only have a few objects in your set, try to use a [http://newgrf-specs.tt-wiki.net/wiki/NML:Objects#Default_object_classes default object class]. If you have a comprehensive set with a lot of objects, it might make sense to define a [http://newgrf-specs.tt-wiki.net/wiki/NML:Objects#Default_object_classes custom class] (register it on the page linked).&lt;br /&gt;
; classname&lt;br /&gt;
: At least one object in each class needs to define the name of the class as string to be displayed in the object construction window.&lt;br /&gt;
; size&lt;br /&gt;
: Define the size in the format &amp;lt;code&amp;gt;[x,y]&amp;lt;/code&amp;gt;. Objects are rectangular up to 15x15 tiles.&lt;br /&gt;
; end_of_life_date&lt;br /&gt;
: At which date the object becomes unavailable for purchase. Can be a &amp;lt;code&amp;gt;date()&amp;lt;/code&amp;gt; or set to &amp;lt;code&amp;gt;0xFFFFFFFF&amp;lt;/code&amp;gt; to use the maximum value possible.&lt;br /&gt;
; height&lt;br /&gt;
: In multiples of 16 pixels. Use 0 for flat objects, 1 for objects up to 16 pixels high, 2 for objects up to 32 pixels high etc.&lt;br /&gt;
; num_views&lt;br /&gt;
: Each object may have 1, 2 or 4 views. This can be used for rotations of the object or alternatively up to four different variations of the same object.&lt;br /&gt;
&lt;br /&gt;
=== graphics block ===&lt;br /&gt;
We&#039;ll add the graphics later, so for now we only define a [http://newgrf-specs.tt-wiki.net/wiki/NML:Objects#Object_callbacks callback] here to show a description of the object in the purchase menu. The callback used for this is &amp;lt;code&amp;gt;additional_text&amp;lt;/code&amp;gt; and can directly return a string from the graphics block.&lt;br /&gt;
&lt;br /&gt;
== Language file ==&lt;br /&gt;
Only English as default language with NewGRF name and description. Also the strings from the item block for the object class name, the own name of the object and a purchase menu description are added&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
##grflangid 0x01&lt;br /&gt;
&lt;br /&gt;
#Main grf title and description&lt;br /&gt;
STR_GRF_NAME        :{TITLE}&lt;br /&gt;
STR_GRF_DESCRIPTION :Description: {SILVER}Dutch Road Furniture is an eyecandy object NewGRF that features road furniture that can be found alongside Dutch roads. {}(c)2011 FooBar. {}{BLACK}License: {SILVER}GPLv2 or higher.&lt;br /&gt;
&lt;br /&gt;
#object classes&lt;br /&gt;
STR_NLRF            :Dutch Road Furniture&lt;br /&gt;
&lt;br /&gt;
#object name and description&lt;br /&gt;
STR_FINGERPOST_3            :Dutch Fingerpost three-way&lt;br /&gt;
STR_FINGERPOST_3_PURCHASE   :The three-way fingerpost is centered at one side of the tile and facing outward. Intended to be placed directly opposite of the secondary road at a three-way junction.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
custom_tags.txt this time contains the &amp;lt;code&amp;gt;{TITLE}&amp;lt;/code&amp;gt; of the NewGRF, see the introduction to [[NMLTutorial/Language_files#Custom_string_codes|language files]] for more details about the usage of custom_tags.txt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
That should have you started nicely. Next we&#039;ll look into spritelayout blocks which are used for the graphics of objects.&lt;br /&gt;
&lt;br /&gt;
{{NMLTutorialNavbar|Train recolour|Spritelayout}}&lt;/div&gt;</summary>
		<author><name>Yexo</name></author>
	</entry>
	<entry>
		<id>https://www.tt-wiki.net/index.php?title=NMLTutorial/Callback_and_switch&amp;diff=7642</id>
		<title>NMLTutorial/Callback and switch</title>
		<link rel="alternate" type="text/html" href="https://www.tt-wiki.net/index.php?title=NMLTutorial/Callback_and_switch&amp;diff=7642"/>
		<updated>2011-08-24T11:37:03Z</updated>

		<summary type="html">&lt;p&gt;Yexo: /* Switch blocks */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{NMLTutorial}}&lt;br /&gt;
&lt;br /&gt;
Callbacks allow to do some fancy things on the fly. Where properties are defined static, callbacks allow to change (some) properties depending on the game state (for instance the game year or what cargo a vehicle is refitted to). Apart from that, some callbacks allow things that are not possible from the usual item definition (such as graphic animations or articulated vehicles).&lt;br /&gt;
&lt;br /&gt;
Callbacks are often used in combination with switches. Switches are things that allow to make a decision based on variables. These variables depend on the game state (so if you for instance want to change vehicle properties depending on the game year, you need a switch attached to the callback). Furthermore, switches can be used to &amp;quot;switch graphics&amp;quot; based on the same variables (e.g. pointing to different spritegroups/sets for each part of an articulated vehicle).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Callbacks ==&lt;br /&gt;
What callbacks are available depend on the [[NMLTutorial/NML Syntax#Features|feature]] you&#039;re working on. Then you can [http://newgrf-specs.tt-wiki.net/wiki/NML:Properties_and_variables_and_callbacks look up] the available callbacks in the NML Documentation. These tables list the names of the callbacks, what they do and what value they want to see returned. Some callbacks need to be pointed to spritegroups, while others want a string or number returned.&lt;br /&gt;
&lt;br /&gt;
Callbacks are defined in the [[NMLTutorial/Item#Graphics block|graphics block]] of the item block and from there they can either directly return a value or point to a switch or spritegroup. Let&#039;s look at the graphics block once more:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
item {&lt;br /&gt;
    graphics {&lt;br /&gt;
        callback: &amp;lt;identifier&amp;gt;|&amp;lt;return_value&amp;gt;;&lt;br /&gt;
        [&amp;lt;callback2&amp;gt;: &amp;lt;identifier2&amp;gt;|&amp;lt;return_value2&amp;gt;;]&lt;br /&gt;
        [...;]&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you want to point the callback to a different block (a switch block or a spritegroup block), you just put the identifier of that block behind the name of the callback. If you want the callback to return a value (string or number) directly, you need to first write the keyword &amp;lt;code&amp;gt;return&amp;lt;/code&amp;gt; and then the numeric value or &amp;lt;code&amp;gt;string()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
So for example (using fictional callback names):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
    graphics {&lt;br /&gt;
        callback_to_spritegroup: spritegroup_identifier;&lt;br /&gt;
        callback_to_switch:      switch_identifier;&lt;br /&gt;
        callback_return_string:  return string(STR_STRINGNAME);&lt;br /&gt;
        callback_return_number:  return 20;&lt;br /&gt;
        default:                 spritegroup_default_graphics;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Please note that all callbacks need to be defined in a &#039;&#039;&#039;single&#039;&#039;&#039; graphics block.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Switch blocks ==&lt;br /&gt;
As written in the introduction, switch blocks can be used to make decisions on certain variables. A switch block can be used to decide a callback return value depending on a variable, or to decide what spritegroup to use for the graphics depending on a variable. You need to [http://newgrf-specs.tt-wiki.net/wiki/NML:Properties_and_variables_and_callbacks look up] what variables are available for the feature you&#039;re using. Don&#039;t forget the [http://newgrf-specs.tt-wiki.net/wiki/NML:General#General_variables general variables] that are available for all features.&lt;br /&gt;
&lt;br /&gt;
If you think you can make these decisions using if/else statements, you&#039;re wrong. Most variables are only available in a switch block of the feature you&#039;re working on. So when working with callbacks and graphics, use switches to make decisions based on variables.&lt;br /&gt;
&lt;br /&gt;
The switch block syntax looks like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
switch (&amp;lt;feature&amp;gt;, &amp;lt;relation&amp;gt;, &amp;lt;identifier&amp;gt;, &amp;lt;variable&amp;gt;) {&lt;br /&gt;
	&amp;lt;range&amp;gt;: &amp;lt;return_value&amp;gt;;&lt;br /&gt;
	&amp;lt;range2&amp;gt;: &amp;lt;return_value2&amp;gt;;&lt;br /&gt;
	&amp;lt;default_return_value&amp;gt;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;lt;feature&amp;gt;&amp;lt;/code&amp;gt;: the [[NMLTutorial/NML Syntax#Features|feature]] you&#039;re working on.&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;lt;relation&amp;gt;&amp;lt;/code&amp;gt;: either &amp;lt;code&amp;gt;SELF&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;PARENT&amp;lt;/code&amp;gt;. This indicates if you want to use the variable of the item itself or that of it&#039;s related item. See the NML Documentation on [http://newgrf-specs.tt-wiki.net/wiki/NML:Switch switch blocks] for a table of what these relations are for each feature.&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;lt;identifier&amp;gt;&amp;lt;/code&amp;gt;: a self-chosen identifier (name) for this switch. It&#039;s useful to start with &#039;&#039;switch_&#039;&#039;.&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;lt;variable&amp;gt;&amp;lt;/code&amp;gt;: the [http://newgrf-specs.tt-wiki.net/wiki/NML:Properties_and_variables_and_callbacks variable] you want to base this decision on&amp;lt;ref&amp;gt;To make things even more complicated, you can use expressions as a variable or even an array of multiple expressions. The last expression from the array is used to make the decision. To make things not even more complicated than they already are, we&#039;ll ignore this possibility for now.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;lt;range&amp;gt;&amp;lt;/code&amp;gt;: Either a single value or a subrange from the value range available to this variable. If you want to specify a subrange, use &amp;lt;code&amp;gt;&amp;lt;range_start&amp;gt;..&amp;lt;range_end&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;lt;return_value&amp;gt;&amp;lt;/code&amp;gt;: An identifier to a different switch or spritegroup block, or (when switching a callback) the &amp;lt;code&amp;gt;return&amp;lt;/code&amp;gt; keyword followed by a number or string reference.&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;lt;default_return_value&amp;gt;&amp;lt;/code&amp;gt;: Like a &amp;lt;code&amp;gt;&amp;lt;return_value&amp;gt;&amp;lt;/code&amp;gt;, but this one is only used if none of the ranges specified above matches the value of the variable.&lt;br /&gt;
&lt;br /&gt;
Now this may sound rather complicated and I agree that it may be a bit overwhelming when presented like this. Switches are one of the most complicated blocks in NML and they represent the VarAction2 in NFO. In case you&#039;re familiar with that: VarAction2 is one of the most complicated things in NFO as well.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Let&#039;s look at a little example showing some of the possibilities of a switch. Note that doesn&#039;t have an actual meaning other than showing some of the options. In reality it will be very uncommon that a single switch blocks needs to have a string returned for one range, a number for another range, point to an other switch for yet another range.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
 switch (FEAT_TRAINS, PARENT, some_vehicle_switch, (position_in_consist) {&lt;br /&gt;
 	0..2:   return string(STRING_FOO_BAR);  //return a text message&lt;br /&gt;
 	3..4:   return;                         //returns 3 in case position_in_consist == 3 or 4 in case position_in_consist == 4&lt;br /&gt;
 	5..300: return 42;                      //42 is always a good answer&lt;br /&gt;
 	400:    switch_other_identifier;        //chain to some other switch block&lt;br /&gt;
 	401:    return num_vehs_in_consist + 1; //return a value with a variable access&lt;br /&gt;
 	CB_FAILED;                              //return a failure result as default&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Because this particular example returns numbers and strings, it can only be a switch for a callback. Switches used for graphics will (only) return identifiers to spritegroups, for example (this is an actual realistic example for a change):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap&amp;quot;&amp;gt;&lt;br /&gt;
 switch (FEAT_TRAINS, PARENT, some_other_vehicle_switch, (position_in_consist) {&lt;br /&gt;
 	1..2:   spritegroup_vehicle_1; //use this for second and third part of articulated vehicle&lt;br /&gt;
 	3..4:   spritegroup_vehicle_2; //use this for fourth and fifth part of articulated vehicle&lt;br /&gt;
 	5:      spritegroup_vehicle_3; //use this for sixth part of articulated vehicle&lt;br /&gt;
 	spritegroup_vehicle_0;         //use this for first and other parts of articulated vehicle (i.e. default)&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There&#039;s much more to say about callbacks and switch blocks, but this is probably intimidating enough already. Next we&#039;ll make an articulated tram vehicle to show you where these callbacks and switches go in your NML code.&lt;br /&gt;
&lt;br /&gt;
{{NMLTutorialNavbar|Road vehicle cargo graphics|Tram}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Yexo</name></author>
	</entry>
	<entry>
		<id>https://www.tt-wiki.net/index.php?title=NMLTutorial/Template&amp;diff=7641</id>
		<title>NMLTutorial/Template</title>
		<link rel="alternate" type="text/html" href="https://www.tt-wiki.net/index.php?title=NMLTutorial/Template&amp;diff=7641"/>
		<updated>2011-08-24T10:51:15Z</updated>

		<summary type="html">&lt;p&gt;Yexo: /* Template parameter magic */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{NMLTutorial}}&lt;br /&gt;
&lt;br /&gt;
If you&#039;ve ever coded a NewGRF before, you&#039;ll know that figuring out the position of sprites and size in a graphics file and aligning them ingame by changing the offsets is a b****. Using templates for the sprite definitions inside spriteset blocks will save you a lot of trouble.&lt;br /&gt;
&lt;br /&gt;
== Templatable graphics files ==&lt;br /&gt;
First you need to make sure that your graphics file(s) are actually templatable. This means that every group of sprites for e.g. a vehicle needs to have the same sprite sizes and the same distances between those sprites. Futhermore each vehicle needs to be aligned consistently within their sprite boxes, otherwise you still end up having to specify custom offsets for each sprite.&lt;br /&gt;
&lt;br /&gt;
If you have vehicles (or buildings or whatever) of different sizes, and still want to use a single template for that, you can make your sprite boxes as big as the largest vehicle (or whatever) and use these big boxes also for smaller sprites.&lt;br /&gt;
&lt;br /&gt;
An example of how to template graphics for trams and road vehicles has been included below. As long as you stick your vehicle sprites in one of these predefined sprite boxes and aligned correctly like the example &#039;blocks&#039;, you can use the same template for the NML sprite code for multiple vehicles. This particular sprite template actually has eight different sprite templates for the eight (default, not counting overhangs) vehicle lengths available in OpenTTD (only use the first four in TTDPatch) and one for the purchase menu sprite. Each of these come with exactly one NML template with the sprite sizes and offsets. So if you have a full length (32px) vehicle, you use the 32px sprite template and the 32px NML templates that belongs to this.&lt;br /&gt;
&lt;br /&gt;
[[Image:FooBarTramVehicleTemplates.png|frame|none|Sprite templates for trams/road vehicles in eight different vehicle lengths. Licensed GPLv2 or higher.]]&lt;br /&gt;
&lt;br /&gt;
We&#039;ll look at the NML template code that belongs to these sprite templates later. The tram vehicle example which will follow later in this tutorial actually uses some of these sprite templates and code. For other premade templates, you can consider looking into the [http://dev.openttdcoop.org/projects/ogfx-rv/repository OpenGFX+ Road Vehicles] or [http://dev.openttdcoop.org/projects/ogfx-trains/repository OpenGFX+ Trains] source.&lt;br /&gt;
&lt;br /&gt;
The actual position of each block of sprites within your graphics file doesn&#039;t matter. This part will be parameterized in the template code. So you can align them nicely in a grid, or just ploink them somewhere randomly, as long as you keep the block of sprites together.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Template block ==&lt;br /&gt;
Let&#039;s now focus on the NML code that should go with a sprite template. The general syntax of the template block is as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
template &amp;lt;templatename&amp;gt;([&amp;lt;param1&amp;gt; [, &amp;lt;param2&amp;gt; [, &amp;lt;param3&amp;gt;...]]]) {&lt;br /&gt;
	&amp;lt;list_of_realsprites&amp;gt;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;&amp;lt;templatename&amp;gt;&amp;lt;/code&amp;gt; is again a name that you choose, although you&#039;re encouraged to start it with &#039;&#039;template_&#039;&#039;. Behind the name, between brackets and separated by commas, you can supply a list of template parameter names that you will use as variables in your template. You can provide any number of template parameters, including none at all. Inside the template block you supply a list of realsprites, just like you would in a normal [[NMLTutorial/Spriteset and spritegroup#&amp;lt;list_of_realsprites&amp;gt;|spriteset]].&lt;br /&gt;
&lt;br /&gt;
=== Template parameter magic ===&lt;br /&gt;
The beauty of the templates are the template parameters. You can vary their values every time you call a template in your NML code, so the template parameter values can be different for every road vehicle. This means that you for instance can make the &amp;lt;code&amp;gt;left_x&amp;lt;/code&amp;gt; in a template a variable.&lt;br /&gt;
&lt;br /&gt;
Combine this with the fact that you can do any mathematical calculation with template parameters on the values, you can make a template as complex as you want.&lt;br /&gt;
&lt;br /&gt;
Now you might find this very theoretical, so let&#039;s look at an example right quick. This will surely help you understand the template concept.&lt;br /&gt;
&lt;br /&gt;
=== Example NML templates ===&lt;br /&gt;
The template examples below belong to the sprite templates from the image above. From the name of the template you can see which one you need for a specific sprite template. So if you used the &#039;&#039;6/8 (24px)&#039;&#039; sprite template, the &amp;lt;code&amp;gt;template_tram_24&amp;lt;/code&amp;gt; is the one that goes with this.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap; max-height: 400px; overflow:scroll&amp;quot;&amp;gt;&lt;br /&gt;
template template_tram_32(x, y) {&lt;br /&gt;
    //[left_x,  upper_y,    width,     height,     offset_x,     offset_y]&lt;br /&gt;
    [x,         y,          10,        28,           -4,         -11]&lt;br /&gt;
    [x+ 20,     y,          26,        28,          -17,         -14]&lt;br /&gt;
    [x+ 50,     y,          36,        28,          -18,         -20]&lt;br /&gt;
    [x+ 90,     y,          26,        28,           -9,         -15]&lt;br /&gt;
    [x+120,     y,          10,        28,           -4,         -11]&lt;br /&gt;
    [x+140,     y,          26,        28,          -16,         -16]&lt;br /&gt;
    [x+170,     y,          36,        28,          -18,         -20]&lt;br /&gt;
    [x+210,     y,          26,        28,           -8,         -16]&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
template template_tram_28(x, y) {&lt;br /&gt;
    //[left_x,  upper_y,    width,     height,     offset_x,     offset_y]&lt;br /&gt;
    [x,         y,          10,        28,           -4,         -11]&lt;br /&gt;
    [x+ 20,     y,          26,        28,          -17,         -14]&lt;br /&gt;
    [x+ 50,     y,          36,        28,          -20,         -20]&lt;br /&gt;
    [x+ 90,     y,          26,        28,           -9,         -15]&lt;br /&gt;
    [x+120,     y,          10,        28,           -4,         -13]&lt;br /&gt;
    [x+140,     y,          26,        28,          -16,         -16]&lt;br /&gt;
    [x+170,     y,          36,        28,          -16,         -20]&lt;br /&gt;
    [x+210,     y,          26,        28,           -8,         -16]&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
template template_tram_24(x, y) {&lt;br /&gt;
    //[left_x,  upper_y,    width,     height,     offset_x,     offset_y]&lt;br /&gt;
    [x,         y,          10,        28,           -4,         -11]&lt;br /&gt;
    [x+ 20,     y,          26,        28,          -17,         -14]&lt;br /&gt;
    [x+ 50,     y,          36,        28,          -22,         -20]&lt;br /&gt;
    [x+ 90,     y,          26,        28,           -9,         -15]&lt;br /&gt;
    [x+120,     y,          10,        28,           -4,         -15]&lt;br /&gt;
    [x+140,     y,          26,        28,          -16,         -16]&lt;br /&gt;
    [x+170,     y,          36,        28,          -14,         -20]&lt;br /&gt;
    [x+210,     y,          26,        28,           -8,         -16]&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
template template_tram_20(x, y) {&lt;br /&gt;
    //[left_x,  upper_y,    width,     height,     offset_x,     offset_y]&lt;br /&gt;
    [x,         y,          10,        28,           -4,         -10]&lt;br /&gt;
    [x+ 20,     y,          26,        28,          -17,         -14]&lt;br /&gt;
    [x+ 50,     y,          36,        28,          -24,         -20]&lt;br /&gt;
    [x+ 90,     y,          26,        28,           -9,         -15]&lt;br /&gt;
    [x+120,     y,          10,        28,           -4,         -16]&lt;br /&gt;
    [x+140,     y,          26,        28,          -16,         -16]&lt;br /&gt;
    [x+170,     y,          36,        28,          -12,         -20]&lt;br /&gt;
    [x+210,     y,          26,        28,           -8,         -16]&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
template template_tram_16(x, y) {&lt;br /&gt;
    //[left_x,  upper_y,    width,     height,     offset_x,     offset_y]&lt;br /&gt;
    [x,         y,          10,        28,           -4,          -9]&lt;br /&gt;
    [x+ 20,     y,          26,        28,          -17,         -14]&lt;br /&gt;
    [x+ 50,     y,          36,        28,          -26,         -20]&lt;br /&gt;
    [x+ 90,     y,          26,        28,           -9,         -15]&lt;br /&gt;
    [x+120,     y,          10,        28,           -4,         -17]&lt;br /&gt;
    [x+140,     y,          26,        28,          -16,         -16]&lt;br /&gt;
    [x+170,     y,          36,        28,          -10,         -20]&lt;br /&gt;
    [x+210,     y,          26,        28,           -8,         -16]&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
template template_tram_12(x, y) {&lt;br /&gt;
    //[left_x,  upper_y,    width,     height,     offset_x,     offset_y]&lt;br /&gt;
    [x,         y,          10,        28,           -4,          -8]&lt;br /&gt;
    [x+ 20,     y,          26,        28,          -17,         -14]&lt;br /&gt;
    [x+ 50,     y,          36,        28,          -28,         -20]&lt;br /&gt;
    [x+ 90,     y,          26,        28,           -9,         -15]&lt;br /&gt;
    [x+120,     y,          10,        28,           -4,         -18]&lt;br /&gt;
    [x+140,     y,          26,        28,          -16,         -16]&lt;br /&gt;
    [x+170,     y,          36,        28,           -8,         -20]&lt;br /&gt;
    [x+210,     y,          26,        28,           -8,         -16]&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
template template_tram_8(x, y) {&lt;br /&gt;
    //[left_x,  upper_y,    width,     height,     offset_x,     offset_y]&lt;br /&gt;
    [x,         y,          10,        28,           -4,          -7]&lt;br /&gt;
    [x+ 20,     y,          26,        28,          -17,         -14]&lt;br /&gt;
    [x+ 50,     y,          36,        28,          -30,         -20]&lt;br /&gt;
    [x+ 90,     y,          26,        28,           -9,         -15]&lt;br /&gt;
    [x+120,     y,          10,        28,           -4,         -19]&lt;br /&gt;
    [x+140,     y,          26,        28,          -16,         -16]&lt;br /&gt;
    [x+170,     y,          36,        28,           -6,         -20]&lt;br /&gt;
    [x+210,     y,          26,        28,           -8,         -16]&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
template template_tram_4(x, y) {&lt;br /&gt;
    //[left_x,  upper_y,    width,     height,     offset_x,     offset_y]&lt;br /&gt;
    [x,         y,          10,        28,           -4,          -6]&lt;br /&gt;
    [x+ 20,     y,          26,        28,          -17,         -14]&lt;br /&gt;
    [x+ 50,     y,          36,        28,          -32,         -20]&lt;br /&gt;
    [x+ 90,     y,          26,        28,           -9,         -15]&lt;br /&gt;
    [x+120,     y,          10,        28,           -4,         -20]&lt;br /&gt;
    [x+140,     y,          26,        28,          -16,         -16]&lt;br /&gt;
    [x+170,     y,          36,        28,           -4,         -20]&lt;br /&gt;
    [x+210,     y,          26,        28,           -8,         -16]&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
template template_purchase(x, y) {&lt;br /&gt;
    //[left_x,  upper_y,    width,     height,     offset_x,     offset_y]&lt;br /&gt;
    [x,         y,          50,        12,          -25,          -6]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In these templates, there are two template parameters &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt;. Whenever you call one of these templates, you specify the horizontal distance between the top left of the graphics file and the top left of the block of sprites as value for &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt; and the vertical distance as value for &amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt;. NML will then calculate the &#039;&#039;left_x&#039;&#039; for each sprite for you and will insert the &#039;&#039;upper_y&#039;&#039; as well.&lt;br /&gt;
&lt;br /&gt;
With some rearranging of the position of the vehicles in their sprite boxes, you could probably come up with a single template that can be used for vehicles of any length, but that is a challenge for you to be accepted.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Calling a template ==&lt;br /&gt;
As with everything, a template can only be called if it&#039;s defined. So templates are best placed shortly after the grf block.&lt;br /&gt;
&lt;br /&gt;
Because a template is an alternative for a sprite definition, you call a template inside a spriteset block (or inside replace or replacenew blocks as those also define sprites). You can use multiple templates in a spriteset block or use one template multiple times consecutively. &lt;br /&gt;
&lt;br /&gt;
So for example if you want to use the &#039;&#039;6/8 (24px)&#039;&#039; sprite template from above, you would define the spriteset for that using a template like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue; white-space: pre-wrap;&amp;quot;&amp;gt;&lt;br /&gt;
spriteset(spriteset_tram_example, &amp;quot;gfx/FooBarTramVehicleTemplates.png&amp;quot;) {&lt;br /&gt;
	template_tram_24(0, 100)&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will use 0 for the value of &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt; and 100 for the value of &amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt; for the template parameters. Also note that you don&#039;t get a semicolon after the call to the template.&lt;br /&gt;
&lt;br /&gt;
With template parameter values 0 and 100, NML will silently substitute &amp;lt;code&amp;gt;template_tram_24(0, 100)&amp;lt;/code&amp;gt; with the recalculated contents from that particular template. The substituted content in this case would be:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    //[left_x,  upper_y,    width,     height,     offset_x,     offset_y]&lt;br /&gt;
    [  0,       100,        10,        28,           -4,         -11]&lt;br /&gt;
    [ 20,       100,        26,        28,          -17,         -14]&lt;br /&gt;
    [ 50,       100,        36,        28,          -22,         -20]&lt;br /&gt;
    [ 90,       100,        26,        28,           -9,         -15]&lt;br /&gt;
    [120,       100,        10,        28,           -4,         -15]&lt;br /&gt;
    [140,       100,        26,        28,          -16,         -16]&lt;br /&gt;
    [170,       100,        36,        28,          -14,         -20]&lt;br /&gt;
    [210,       100,        26,        28,           -8,         -16]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Remember our road vehicle had two spritesets? These are templatable, so let&#039;s do that next!&lt;br /&gt;
&lt;br /&gt;
{{NMLTutorialNavbar|Road vehicle graphics|Road vehicle graphics template}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Yexo</name></author>
	</entry>
	<entry>
		<id>https://www.tt-wiki.net/index.php?title=NMLTutorial/Starting_an_NML_file&amp;diff=7614</id>
		<title>NMLTutorial/Starting an NML file</title>
		<link rel="alternate" type="text/html" href="https://www.tt-wiki.net/index.php?title=NMLTutorial/Starting_an_NML_file&amp;diff=7614"/>
		<updated>2011-08-22T22:12:37Z</updated>

		<summary type="html">&lt;p&gt;Yexo: /* Summarizing */ don&amp;#039;t advocate -u, -c is good, but not necesary for a basic tutorial&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{NMLTutorial}}&lt;br /&gt;
&lt;br /&gt;
It&#039;s time to create your first NML file! All this reading must have made you hungry by now, so let&#039;s continue right quick.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Where to put the NML file ==&lt;br /&gt;
&lt;br /&gt;
From the [[NMLTutorial/Language files|Language files]] section you may remember this folder structure:&lt;br /&gt;
&lt;br /&gt;
 mygrf&lt;br /&gt;
  |- lang&lt;br /&gt;
  |   |- english.lng&lt;br /&gt;
  |   |- other_language.lng&lt;br /&gt;
  |- custom_tags.txt&lt;br /&gt;
  |- mygrf.nml&lt;br /&gt;
&lt;br /&gt;
This is exactly where the NML file should go: one folder above the language files, and in the same folder as custom_tags.txt. You can name the file any way you want, but try to avoid spaces. Create it either from the file explorer or from your text editor.&lt;br /&gt;
&lt;br /&gt;
== The grf block ==&lt;br /&gt;
Nearly all NML files will start with a grf block. The grf block takes no parameters and is one of the simplest blocks there is. Your NML file also has no more than one grf block. NML files without a grf block are only useful for &#039;&#039;base graphic&#039;&#039; files such as the grf files from OpenGFX. So chances are that you need a grf block.&lt;br /&gt;
&lt;br /&gt;
The general syntax of the grf block is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
grf {&lt;br /&gt;
	grfid: &amp;lt;literal-string&amp;gt;;&lt;br /&gt;
	name: &amp;lt;string&amp;gt;;&lt;br /&gt;
	desc: &amp;lt;string&amp;gt;;&lt;br /&gt;
	version: &amp;lt;expression&amp;gt;;&lt;br /&gt;
	min_compatible_version: &amp;lt;expression&amp;gt;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We&#039;ll be looking at every line of this grf block and give you an example how to fill it in.&lt;br /&gt;
&lt;br /&gt;
=== Line 1: grf { ===&lt;br /&gt;
This indicates the start of the grf block and the &#039;&#039;opening curly bracket&#039;&#039; defines the start of it&#039;s contents. Just type it in your editor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue&amp;quot;&amp;gt;&lt;br /&gt;
grf {&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 2: grfid: &amp;lt;literal-string&amp;gt;; ===&lt;br /&gt;
This defines the GRFID of your NewGRF. A GRFID is a four-byte string that should be unique. If two NewGRFs have the same GRFID, only one can be used at a time and in OpenTTD chances are only one shows up in the NewGRF list. It&#039;s a convention to use the first two bytes for the creator&#039;s initials. The last two bytes should be numbers, typically the first number identifying which of the author&#039;s sets this is, and the second number being a version number.&lt;br /&gt;
&lt;br /&gt;
The GRFID must be written as a quoted string, but now comes the complicated part: one character is one byte, but one byte is two hexadecimal characters. The first two bytes are best written as a normal quoted string. The last two are best written as escaped bytes, as this allows for 256 sets/versions rather than just 10.&lt;br /&gt;
&lt;br /&gt;
So if your name is Simon Foster and you&#039;re starting the first version of your first set, your GRFID can be &amp;lt;code&amp;gt;&amp;quot;SF\01\01&amp;quot;&amp;lt;/code&amp;gt;. This way, your GRFID is exactly four bytes: two normal characters S and F, and two escaped bytes 01. The backslash indicates that the next two characters together make one byte. When using escaped bytes, remember that they are in hex and as such can only consist the numbers 0-9 and letters A-F. See [http://en.wikipedia.org/wiki/Hexadecimal Wikipedia] for more details on the hexadecimal numeral system.&lt;br /&gt;
&lt;br /&gt;
Now your second line of the nml file will be (but then with your own GRFID):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue&amp;quot;&amp;gt;&lt;br /&gt;
	grfid: &amp;quot;SF\01\01&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 3: name: &amp;lt;string&amp;gt;; ===&lt;br /&gt;
This is the name of your NewGRF, as displayed ingame. NML expects a reference to a string in your language file here. Luckily, we [[NMLTutorial/Language files|already]] put a name for our NewGRF in there. Open the language file and check what name you attached to the string. In our example that would be &amp;lt;code&amp;gt;STR_GRF_NAME&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
To tell NML to use a string from the language file, you have to use the function &amp;lt;code&amp;gt;string(&amp;lt;string-name&amp;gt;)&amp;lt;/code&amp;gt;, replacing &amp;lt;code&amp;gt;&amp;lt;string-name&amp;gt;&amp;lt;/code&amp;gt; with the actual name of the string. This gives us &amp;lt;code&amp;gt;string(STR_GRF_NAME)&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Put this in the third line:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue&amp;quot;&amp;gt;&lt;br /&gt;
	name: string(STR_GRF_NAME);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 4: desc: &amp;lt;string&amp;gt;; ===&lt;br /&gt;
The description is similar to the name of the NewGRF. Again look up the name of the string in the language file and use the &amp;lt;code&amp;gt;string()&amp;lt;/code&amp;gt; function to put it in the grf block. Line four:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue&amp;quot;&amp;gt;&lt;br /&gt;
	desc: string(STR_GRF_DESCRIPTION);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 5: version: &amp;lt;expression&amp;gt;; ===&lt;br /&gt;
Another version? Yes. If your NewGRF is aimed at (but not limited to) OpenTTD you should use this to indicate the actual version and leave the GRFID constant. If your NewGRF is aimed at (but not limited to) TTDPatch you still should provide this version number, but &#039;&#039;bump the GRFID&#039;&#039; whenever a new release is not compatible with the previous release. More on this at the end of this page.&lt;br /&gt;
&lt;br /&gt;
The first release of your NewGRF will start with version 0 and every subsequent release you will increase this value. In case you use a version control system, set this to the revision number.&lt;br /&gt;
&lt;br /&gt;
This gives line five:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue&amp;quot;&amp;gt;&lt;br /&gt;
	version: 0;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 6: min_compatible_version: &amp;lt;expression&amp;gt;; ===&lt;br /&gt;
For the first release, the minimal compatible version is also 0. Leave it at 0 for as long as subsequent releases are compatible with all previous releases. Whenever you need to break compatibility, you set this to the version number (from above) in which you have broken the compatibility.&lt;br /&gt;
&lt;br /&gt;
Line six:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue&amp;quot;&amp;gt;&lt;br /&gt;
	min_compatible_version: 0;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 7: } ===&lt;br /&gt;
The &#039;&#039;closing curly bracket&#039;&#039; defines the end of the grf block; it closes it if you will.&lt;br /&gt;
&lt;br /&gt;
Just type a curly bracket on line seven:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue&amp;quot;&amp;gt;&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Summarizing ==&lt;br /&gt;
Already? You haven&#039;t told us about the semicolons at the end of each line in the grf block!&lt;br /&gt;
&lt;br /&gt;
I haven&#039;t? Well, let&#039;s do that now then...&lt;br /&gt;
&lt;br /&gt;
=== Semicolons ===&lt;br /&gt;
Like in a lot of other programming languages, a semicolon defines the end of an instruction. You must use these at the end of every instruction inside and outside a block, but not on lines that open or close a block (with a curly bracket).&lt;br /&gt;
&lt;br /&gt;
The usage of semicolons in NML is identical (with the exception of templates) to that in Java or C-family (or PHP) languages. It allows to have multiple instructions on one line, which is useful in some cases.&lt;br /&gt;
&lt;br /&gt;
=== Summarizing ===&lt;br /&gt;
This completes our grf block. All lines together, the example looks like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:darkblue&amp;quot;&amp;gt;&lt;br /&gt;
grf {&lt;br /&gt;
	grfid: &amp;quot;SF\01\01&amp;quot;;&lt;br /&gt;
	name: string(STR_GRF_NAME);&lt;br /&gt;
	desc: string(STR_GRF_DESCRIPTION);&lt;br /&gt;
	version: 0;&lt;br /&gt;
	min_compatible_version: 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you like, you can encode this into a grf to see if it works. The grf will not do anything, but it should show up in the game if you add it.&lt;br /&gt;
&lt;br /&gt;
You still remember how to use &#039;&#039;nmlc&#039; on the command line, right? If not, check the [[NMLTutorial/Installation|Installation page]] with the details for your operating system, or maybe the following pointer is enough to get you going:&lt;br /&gt;
&lt;br /&gt;
 nmlc --grf mygrf.grf mygrf.nml&lt;br /&gt;
&lt;br /&gt;
{{NMLTutorialNavbar|NML Syntax|Road vehicle}} &amp;lt;!-- this is here a second time because not everybody may need to read the following section --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Breaking compatibility ==&lt;br /&gt;
Sometimes it happens that you have to break compatibility between different releases of your NewGRF. The NML Documentation has a separate chapter on [http://newgrf-specs.tt-wiki.net/wiki/NML:NewGRF_compatibility NewGRF compatibility] and what actions break compatibility and how to avoid breaking it in the first place.&lt;br /&gt;
&lt;br /&gt;
However, if you must break compatibility, here&#039;s how to handle the version information in your NML file.&lt;br /&gt;
&lt;br /&gt;
=== OpenTTD targeted NewGRFs ===&lt;br /&gt;
* Keep the GRFID you have;&lt;br /&gt;
* Don&#039;t forget to update &amp;lt;code&amp;gt;grf { version }&amp;lt;/code&amp;gt;;&lt;br /&gt;
* Set &amp;lt;code&amp;gt;grf { min_compatible_version }&amp;lt;/code&amp;gt; to the value of &amp;lt;code&amp;gt;grf { version }&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
This way, OpenTTD will hide the old release from the NewGRF window while keeping it available for older savegames to use (provided the user doesn&#039;t delete the old release). Old releases can still be downloaded from BaNaNaS for old savegames.&lt;br /&gt;
&lt;br /&gt;
=== TTDPatch targeted NewGRFs ===&lt;br /&gt;
TTDPatch doesn&#039;t have a concept for &amp;lt;code&amp;gt;grf { min_compatible_version }&amp;lt;/code&amp;gt; (or &amp;lt;code&amp;gt;grf { version }&amp;lt;/code&amp;gt; for that matter). The only way to indicate broken compatibility in TTDPatch is to bump the GRFID. This means that you increase the last byte of the GRFID by one. So if your initial GRFID is &amp;lt;code&amp;gt;&amp;quot;SF\01\01&amp;quot;&amp;lt;/code&amp;gt;, change it to &amp;lt;code&amp;gt;&amp;quot;SF\01\02&amp;quot;&amp;lt;/code&amp;gt; for the next release.&lt;br /&gt;
&lt;br /&gt;
As a consequence, both NewGRFs can be used separate from each other and in OpenTTD both will show up in the NewGRF window. &lt;br /&gt;
&lt;br /&gt;
In order to avoid loading both the old version and the new version in the same game, you have to add a [[NMLTutorial/Version check|version check]] to the NewGRF in order to disable itself (or the older version).&lt;br /&gt;
&lt;br /&gt;
{{NMLTutorialNavbar|NML Syntax|Road vehicle}}&lt;/div&gt;</summary>
		<author><name>Yexo</name></author>
	</entry>
	<entry>
		<id>https://www.tt-wiki.net/index.php?title=NMLTutorial/Installation&amp;diff=7613</id>
		<title>NMLTutorial/Installation</title>
		<link rel="alternate" type="text/html" href="https://www.tt-wiki.net/index.php?title=NMLTutorial/Installation&amp;diff=7613"/>
		<updated>2011-08-22T21:48:26Z</updated>

		<summary type="html">&lt;p&gt;Yexo: /* Using NML */ -u is not the same as -c&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{NMLTutorial}}&lt;br /&gt;
&lt;br /&gt;
NML is written in Python and therefore can be made to run on every operating system that can run Python. This includes the popular operating sytems Linux, MacOS and Windows. Below you&#039;ll find a description on how to install NML and how to use the commandline NML program on your operating system (MacOS description currently missing, as I don&#039;t have that, but please add it).&lt;br /&gt;
&lt;br /&gt;
{{Note|The NML Documentation reflects the latest state of the NML program. Make sure to update your NML regularly, especially if you find something not working that should work according to the documentation.}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Linux ==&lt;br /&gt;
NML requires Pyton, the Python Image Library and Ply. These three things are best installed from your package manager. If you&#039;re looking to compiling NML yourself, you also need the Python Setuptools. Note that NML currently only runs on Python 2.5 through 2.7, but not 3.x. Look for the following in your package manager:&lt;br /&gt;
* python (you might already have this)&lt;br /&gt;
* python-imaging (pil)&lt;br /&gt;
* python-ply&lt;br /&gt;
* python-setuptools&lt;br /&gt;
&lt;br /&gt;
=== Installing NML as precompiled binary (recommended) ===&lt;br /&gt;
The latest version of NML is available as RPM package from the #openttdcoop DevZone. You can find it here: http://bundles.openttdcoop.org/nml/nightlies/LATEST/rpms/. This package is known to work on openSUSE and Red Hat (including Fedora and CentOS) distributions.&lt;br /&gt;
&lt;br /&gt;
You can use the terminal to install this package through your package manager (make sure to run it as superuser). For example on Fedora:&lt;br /&gt;
&lt;br /&gt;
 sudo bash&lt;br /&gt;
 yum install &amp;lt;nowiki&amp;gt;http://bundles.openttdcoop.org/nml/nightlies/LATEST/rpms/nml-rXXXX-suseYYYY.noarch.rpm&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Make sure to replace XXXX and YYYY in the url with the actual version numbers you found via the link above. Enter &amp;quot;y&amp;quot; when asked and when done don&#039;t forget to &amp;lt;code&amp;gt;exit&amp;lt;/code&amp;gt; sudo again, preventing yourself from doing stupid things from this point.&lt;br /&gt;
&lt;br /&gt;
=== Compiling NML yourself ===&lt;br /&gt;
The other option to get NML is to compile it yourself. First you need to get the source from http://bundles.openttdcoop.org/nml/nightlies/LATEST/ or via Mercurial checkout from http://hg.openttdcoop.org/nml (&amp;lt;code&amp;gt;hg clone &amp;lt;nowiki&amp;gt;http://hg.openttdcoop.org/nml&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Also this time you need the terminal as superuser. Then change directory to the (extracted) NML source and run &amp;lt;code&amp;gt;python setup.py install&amp;lt;/code&amp;gt;. For example:&lt;br /&gt;
&lt;br /&gt;
 sudo bash&lt;br /&gt;
 cd ~/Downloads/nml-rXXXX&lt;br /&gt;
 python setup.py install&lt;br /&gt;
 exit&lt;br /&gt;
&lt;br /&gt;
=== Using NML ===&lt;br /&gt;
As said before, NML is a commandline program and therefore doesn&#039;t have a GUI; much like GRFCodec in fact. That means you need to run it from a terminal window. The NML program itself is called &amp;lt;code&amp;gt;nmlc&amp;lt;/code&amp;gt; and the general usage is &amp;lt;code&amp;gt;nmlc [options] &amp;lt;filename&amp;gt;&amp;lt;/code&amp;gt;. First change directory to the directory which has your nml file. Then run the nmlc program to compile your grf. For example:&lt;br /&gt;
&lt;br /&gt;
 cd ~/grfs/mygrf&lt;br /&gt;
 nmlc -c --grf mygrf.grf mygrf.nml&lt;br /&gt;
&lt;br /&gt;
This will encode the nml file ~/grfs/mygrf/mygrf.nml into the grf file ~/grfs/mygrf/mygrf.grf. The -c option is not mandatory, but crops extraneous blue from sprites, reducing the filesize of the grf file.&lt;br /&gt;
&lt;br /&gt;
All commandline options available to NML are available via &amp;lt;code&amp;gt;nmlc -h&amp;lt;/code&amp;gt; and are also listed at the end of this page. Now that you have NML and know how to use it, you can continue this tutorial to learn how to create an actual grf file using NML.&lt;br /&gt;
&lt;br /&gt;
== Windows ==&lt;br /&gt;
NML is available as prebuilt (32 bit) Windows executable from the #openttdcoop DevZone, so there is no need to compile it yourself.&lt;br /&gt;
&lt;br /&gt;
=== Installing NML ===&lt;br /&gt;
Go to http://bundles.openttdcoop.org/nml/nightlies/LATEST/ and download nml-rXXXX-windows-win32.zip, replacing XXXX with the actual version number of the package. The zip file contains a number of files that all need to stay together, so extract the zip file entirely into a single folder, for example D:\grfs\nml.&lt;br /&gt;
&lt;br /&gt;
If you leave it at this, you can already start to use NML, but only from that folder, which makes compiling grfs a bit more difficult as you have to write full paths when encoding a grf file. If you want to run nml from any directory, you need to add the directory containing the nmlc.exe executable to your PATH environment variable. As this can break Windows if you don&#039;t do this properly, we&#039;ll not be explaining this here and we&#039;ll be explaining the long route here. You&#039;re of course free to change your PATH yourself; if you do, you&#039;re probably also smart enough to know how to change the commands as explained in the section below.&lt;br /&gt;
&lt;br /&gt;
=== Using NML ===&lt;br /&gt;
As said before, NML is a commandline program and therefore doesn&#039;t have a GUI; much like GRFCodec in fact. That means you need to run it from a command prompt window. You can start the command prompt from Start &amp;gt; Programs &amp;gt; Accessories &amp;gt; Command Prompt. Or by entering &amp;lt;code&amp;gt;cmd&amp;lt;/code&amp;gt; into the Run dialog or the Start menu search bar.&lt;br /&gt;
&lt;br /&gt;
Next, you need to change directory to the folder where you have nmlc.exe in. Then you can run NML from there. For the example below we&#039;ll be assuming the following:&lt;br /&gt;
* nmlc.exe and related files are in D:\grfs\nml&lt;br /&gt;
* The nml file you want to encode is D:\grfs\mygrf\mygrf.nml&lt;br /&gt;
* The grf file to be created needs to go into D:\grfs\mygrf\mygrf.grf&lt;br /&gt;
&lt;br /&gt;
From the command prompt you can now run the follow commands, one at a time, confirm with Enter after each line:&lt;br /&gt;
&lt;br /&gt;
 D:&lt;br /&gt;
 cd D:\grfs\nml&lt;br /&gt;
 nmlc -u --grf D:\grfs\mygrf\mygrf.grf D:\grfs\mygrf\mygrf.nml&lt;br /&gt;
&lt;br /&gt;
This will encode the nml file D:\grfs\mygrf\mygrf.nml into the grf file D:\grfs\mygrf\mygrf.grf. The -u option is not mandatory, but crops extraneous blue from sprites, reducing the filesize of the grf file. Note that if you have any spaces in a folder of file name, you need to enclose the complete path in double quotes, e.g.: &amp;lt;code&amp;gt;nmlc -u --grf &amp;quot;D:\grfs\my grf\mygrf.grf&amp;quot; &amp;quot;D:\grfs\mgrf\mygrf.nml&amp;quot;&amp;lt;/code&amp;gt;. It is therefore recommended not to have any spaces.&lt;br /&gt;
&lt;br /&gt;
All commandline options available to NML are available via the &amp;lt;code&amp;gt;nmlc -h&amp;lt;/code&amp;gt; command and are also listed at the end of this page. Now that you have NML and know how to use it, you can continue this tutorial to learn how to create an actual grf file using NML.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== NML Commandline Options ==&lt;br /&gt;
&#039;&#039;From the NML readme&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
 Usage: nmlc [options] &amp;lt;filename&amp;gt;&lt;br /&gt;
 Where &amp;lt;filename&amp;gt; is the nml file to parse&lt;br /&gt;
 &lt;br /&gt;
 Options:&lt;br /&gt;
  --version             show program&#039;s version number and exit&lt;br /&gt;
  -h, --help            show this help message and exit&lt;br /&gt;
  -d, --debug           write the AST to stdout&lt;br /&gt;
  -s, --stack           Dump stack when an error occurs&lt;br /&gt;
  --grf=&amp;lt;file&amp;gt;          write the resulting grf to &amp;lt;file&amp;gt;&lt;br /&gt;
  --nfo=&amp;lt;file&amp;gt;          write nfo output to &amp;lt;file&amp;gt;&lt;br /&gt;
  -c                    crop extraneous transparent blue from real sprites&lt;br /&gt;
  -u                    save uncompressed data in the grf file&lt;br /&gt;
  --nml=&amp;lt;file&amp;gt;          write optimized nml to &amp;lt;file&amp;gt;&lt;br /&gt;
  -o &amp;lt;file&amp;gt;, --output=&amp;lt;file&amp;gt;&lt;br /&gt;
                        write output(nfo/grf) to &amp;lt;file&amp;gt;&lt;br /&gt;
  -t &amp;lt;file&amp;gt;, --custom-tags=&amp;lt;file&amp;gt;&lt;br /&gt;
                        Load custom tags from &amp;lt;file&amp;gt; [default:&lt;br /&gt;
                        custom_tags.txt]&lt;br /&gt;
  -l &amp;lt;dir&amp;gt;, --lang-dir=&amp;lt;dir&amp;gt;&lt;br /&gt;
                        Load language files from directory &amp;lt;dir&amp;gt; [default:&lt;br /&gt;
                        lang]&lt;br /&gt;
  -a &amp;lt;dir&amp;gt;, --sprites-dir=&amp;lt;dir&amp;gt;&lt;br /&gt;
                        Store 32bpp sprites in directory &amp;lt;dir&amp;gt; [default:&lt;br /&gt;
                        sprites]&lt;br /&gt;
  --default-lang=&amp;lt;file&amp;gt;&lt;br /&gt;
                        The default language is stored in &amp;lt;file&amp;gt; [default:&lt;br /&gt;
                        english.lng]&lt;br /&gt;
  --start-sprite=&amp;lt;num&amp;gt;  Set the first sprite number to write (do not use&lt;br /&gt;
                        except when you output nfo that you want to include in&lt;br /&gt;
                        other files)&lt;br /&gt;
  -p &amp;lt;palette&amp;gt;, --palette=&amp;lt;palette&amp;gt;&lt;br /&gt;
                        Force nml to use the palette &amp;lt;pal&amp;gt; [default: ANY].&lt;br /&gt;
                        Valid values are &#039;DOS&#039;, &#039;WIN&#039;, &#039;ANY&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Text editor ==&lt;br /&gt;
NML files and its language files are plain text files and should be edited in a plain text editor. Your operating system most likely comes with a text editor with limited functionality. As such it is recommended to choose an editor with more functionality:&lt;br /&gt;
; Cross-platform&lt;br /&gt;
* [http://www.geany.org/ Geany]&lt;br /&gt;
; Linux&lt;br /&gt;
; MacOS&lt;br /&gt;
; Windows&lt;br /&gt;
* [http://notepad-plus-plus.org/ Notepad++]&lt;br /&gt;
&lt;br /&gt;
=== Syntax highlighting ===&lt;br /&gt;
Syntax highlighting adds some colour to NML code, which makes it easier to read.&lt;br /&gt;
&lt;br /&gt;
At the #openttdcoop DevZone there are syntax highlighter extensions available for [http://dev.openttdcoop.org/documents/24 Notepad++] and [http://dev.openttdcoop.org/documents/26 Geany]. If you want to create your own syntax highlighter, there&#039;s a [http://dev.openttdcoop.org/documents/25 script] available as well that will help you create the keyword lists.&lt;br /&gt;
&lt;br /&gt;
{{NMLTutorialNavbar||Graphic files}}&lt;/div&gt;</summary>
		<author><name>Yexo</name></author>
	</entry>
	<entry>
		<id>https://www.tt-wiki.net/index.php?title=NMLTutorial&amp;diff=6726</id>
		<title>NMLTutorial</title>
		<link rel="alternate" type="text/html" href="https://www.tt-wiki.net/index.php?title=NMLTutorial&amp;diff=6726"/>
		<updated>2011-06-21T20:11:40Z</updated>

		<summary type="html">&lt;p&gt;Yexo: /* Example */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
Since june 2010 a new coding language for creating TTDpatch/OpenTTD GRF&#039;s exists: Newgrf Meta Language or NML. It differs significantly from the old way of GRF editing and although [http://hg.openttdcoop.org/nml/raw-file/tip/docs/index.html documentation] is available it may still be a challenge for people interested in using NML code.&lt;br /&gt;
&lt;br /&gt;
There will be detailed examples of how coding in NML works on this new TT-wiki. Make sure to check the progress of this NML tutorial regularly.&lt;br /&gt;
&lt;br /&gt;
==NML vs. NFO==&lt;br /&gt;
===Background===&lt;br /&gt;
NML is a high-level NewGRF language compiler which compiles NML and LNG files into newgrf files (and NFO files, if asked to do so). Coding a NewGRF in NML is similar to writing in any other programming language except that there are no real sub-routines; you can use the usual definition and condition statements.&lt;br /&gt;
&lt;br /&gt;
===Language support===&lt;br /&gt;
NML provides easy support for different languages in one GRF. This is achieved by creating language files (LNG). These language files follow the convention used for OpenTTD translation files. When compiling NML files a search for language files will automatically be performed. Even without providing additional translations at least one language file must be specified, called default.lng.&lt;br /&gt;
&lt;br /&gt;
===Image format support===&lt;br /&gt;
One of the conveniences of NML is the possibility to read other image formats, most notably [http://en.wikipedia.org/wiki/Portable_Network_Graphics PNG]. Remember though that those images still need to supply the proper 8bpp palette and are supported by the python image library.&lt;br /&gt;
&lt;br /&gt;
===Example===&lt;br /&gt;
Does the above sound impressive, maybe even threatening to you? One illustration often says more than a thousand words so let&#039;s show the difference with two illustrations:&lt;br /&gt;
&lt;br /&gt;
{| cellspacing=&amp;quot;0&amp;quot; class=&amp;quot;mainpagetable&amp;quot; text-align=&amp;quot;left&amp;quot; style=&amp;quot;background-color: #F8EABA; border: 1px solid #C0C090;&amp;quot;&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
&lt;br /&gt;
|width=&amp;quot;50%&amp;quot;|&lt;br /&gt;
&amp;lt;font size=&amp;quot;3&amp;quot;&amp;gt;&#039;&#039;&#039;NFO code snippet&#039;&#039;&#039;&amp;lt;/font&amp;gt;&lt;br /&gt;
:// Automatically generated by GRFCODEC. Do not modify!&lt;br /&gt;
:// (Info version 7)&lt;br /&gt;
:// Escapes: 2+ = 71 = D= = DR 2- = 70 = D+ = DF 2&amp;lt; = 7= = D- = DC 2&amp;gt; = 7! = Du* = DM 2u&amp;lt; = 7&amp;lt; = D* = DnF 2u&amp;gt; = 7&amp;gt; = Du&amp;lt;&amp;lt; = DnC &lt;br /&gt;
:2/ = 7G = D&amp;lt;&amp;lt; = DO 2% = 7g = D&amp;amp; 2u/ = 7gG = D| 2u% = 7GG = Du/ 2* = 7gg = D/ 2&amp;amp; = 7c = Du% 2| = 7C = D% 2^ 2sto = 2s 2rst = 2r 2+ 2ror = 2rot&lt;br /&gt;
:// Format: spritenum pcxfile xpos ypos compression ysize xsize xrel yrel&lt;br /&gt;
&lt;br /&gt;
:0 * 4 \d416 &lt;br /&gt;
:1 * 92 08 07 &amp;quot;SER0&amp;quot; &amp;quot;ÞSwedish Rails  nightly-r52M&amp;quot; 00 &amp;quot;ÞSwedish rails are a replacement for the default rails&amp;quot; 00&lt;br /&gt;
|width=&amp;quot;50%&amp;quot;|&lt;br /&gt;
&amp;lt;font size=&amp;quot;3&amp;quot;&amp;gt;&#039;&#039;&#039;NML code snippet&#039;&#039;&#039;&amp;lt;/font&amp;gt;&lt;br /&gt;
:grf {&lt;br /&gt;
::grfid : &amp;quot;SER0&amp;quot;;&lt;br /&gt;
::name : string(STR_GRF_NAME);&lt;br /&gt;
::desc : string(STR_GRF_DESCRIPTION);&lt;br /&gt;
:}&lt;br /&gt;
&amp;lt;font size=&amp;quot;3&amp;quot;&amp;gt;&#039;&#039;&#039;NML laguage file snippet&#039;&#039;&#039;&amp;lt;/font&amp;gt;&lt;br /&gt;
:&amp;lt;nowiki&amp;gt;##&amp;lt;/nowiki&amp;gt;grflangid 0x01&lt;br /&gt;
:STR_GRF_NAME                                                    :Swedish Rails {VERSION}&lt;br /&gt;
:STR_GRF_DESCRIPTION                                             :Swedish rails are a replacement for the default rails&lt;br /&gt;
|}&lt;br /&gt;
[[Category:NML]][[Category:Tutorials]]&lt;/div&gt;</summary>
		<author><name>Yexo</name></author>
	</entry>
	<entry>
		<id>https://www.tt-wiki.net/index.php?title=NMLTutorial&amp;diff=6630</id>
		<title>NMLTutorial</title>
		<link rel="alternate" type="text/html" href="https://www.tt-wiki.net/index.php?title=NMLTutorial&amp;diff=6630"/>
		<updated>2011-06-19T16:26:51Z</updated>

		<summary type="html">&lt;p&gt;Yexo: fix link to docs&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction to Newgrf Meta Language (NML)==&lt;br /&gt;
&lt;br /&gt;
Since june 2010 a new coding language for creating TTDpatch/OpenTTD GRF&#039;s exists: Newgrf Meta Language or NML. It differs significantly from the old way of GRF editing and although [http://hg.openttdcoop.org/nml/raw-file/tip/docs/index.html documentation] is available it may still be a challenge for people interested in using NML code.&lt;br /&gt;
&lt;br /&gt;
There will be detailed examples of how coding in NML works on this new TT-wiki. Make sure to check the progress of this NML tutorial regularly.&lt;/div&gt;</summary>
		<author><name>Yexo</name></author>
	</entry>
</feed>