CUSTOM TEMPLATES

The default templates can generally cover a high number of the most common interactions and instruments required inside of an aircraft, but they only cover instruments that are used in the official Microsoft Flight Simulator 2024 aircraft. This means that you may run into instruments that do not have a template that can be used "as is", and so will need a custom template.

NOTE: While custom templates can be defined directly inside of the model XML, it is generally advised to define them in one or more separate files, which are then included in your model XML. This helps your workflow by separating the implementation of the template from the data given to it. THis is generally easier to follow and implement as it allows you to switch between the files rather than having to navigate a single massive XML file.

 

 

Create The File

The creation of a custom template XML library file requires you to to have a root <CompileBehaviors> tag, and inside this there will usually be one or more <Include> tags (which can be used to include the files defining the other templates that will be used). This means that the file contents will initially look something like this:

<?xml version="1.0" encoding="utf-8"?>
<CompileBehaviors>
    <Include ModelBehaviorFile="Asobo_EX1\Generic\Index.xml"/>
    <Template Name="MyTemplate">
        <Parameters Type="Default">
            <EXIT_TEMPLATE>MyOtherTemplate</EXIT_TEMPLATE>
        </Parameters>
        <UseTemplate Name="#EXIT_TEMPLATE#">
        </UseTemplate>
    </Template>
</CompileBehaviors>

 

 

Input Events

Most complicated templates will include - and/or require - interactions. These are now best handled using Input Events, which are fully supported using the templates system. Generally, using one or more of the Base Templates is the preferred method for dealing with input, as it is often easier since they handle the complexity of creating an Input Event from scratch. However, it may be necessary to create your own at some point, so here we provide more details on what the base templates do, and also provide some context should you come across some code that is not using the Base Templates.

NOTE: There is already extensive information about Input Events in the documentation and we strongly recommend that you look it over before continuing - Input Events

 

The following three examples will all generate the same interaction and animation, so it is advised to use the Base Template method, as it is easier to implement and ensures that you have an Input Event properly set up.

 

Interaction Template Created From Scratch

The first method for creating your own interactions is to start from zero and create the template completely by hand. This gives you full control over the behavior of your template, but will generally take longer to do than when using the other solutions listed here.

 

Below is an example of a custom template, created from scratch, that shows a generic input:

<Template Name="MyPushButton">
    <Parameters Type="Default">
        <NODE_ID>MyNode</NODE_ID>
        <ANIM_NAME>MyAnim</ANIM_NAME>
        <TOOLTIP_TITLE>@TT_MyAircraft.NAME_OF_MY_TT_TITLE</TOOLTIP_TITLE>
        <TT_DESCRIPTION_ID>@TT_MyAircraft.NAME_OF_MY_TT_ACTION</TT_DESCRIPTION_ID>
    </Parameters>
    <Parameters Type="Override">
        <BTN_ID>MyIEName</BTN_ID><!-- Name of the Input Event -->
        <IS_ON>(O:MyVar)</IS_ON><!-- This Param is used as a shorthand below -->
    </Parameters>
    <Component ID="MyComponent" Node="#NODE_ID#">
        <UseTemplate Name="ASOBO_GT_Anim_Code"> <!-- Animation -->
            <ANIM_CODE>(O:_ButtonAnimVar) 100 *</ANIM_CODE>
            <ANIM_LAG>400</ANIM_LAG>
        </UseTemplate>
        <UseTemplate Name = "ASOBO_GT_AnimTriggers_2SoundEvents"> <!-- Audio -->
            <!-- Also uses ANIM_NAME -->
            <WWISE_EVENT_1>button_switch_generic</WWISE_EVENT_1>
            <WWISE_EVENT_2>button_switch_generic</WWISE_EVENT_2>
        </UseTemplate>
        <UseInputEvent ID="INSTRUMENT"> <!-- Input Event -->
            <TT_ICON>Push</TT_ICON>
            <TT_INTERACTION>PRIMARY_DOWN</TT_INTERACTION>
            <TT_INTERACTION_LOCKABLE>LOCK</TT_INTERACTION_LOCKABLE>
            <SET_STATE_EXTERNAL>#IS_ON# p0 != if{ p0 (&gt;O:MyVar) }</SET_STATE_EXTERNAL>
            <GET_STATE_EXTERNAL>#IS_ON# sp0</GET_STATE_EXTERNAL>
            <SIM_STATE_IS_ON_EXTERNAL>l0</SIM_STATE_IS_ON_EXTERNAL>
            <TT_VALUE>(O:MyVar) @TT_OnOff_Cond</TT_VALUE>
            <TT_VALUE_IS_DYNAMIC>True</TT_VALUE_IS_DYNAMIC>
            <ANIM>EXTERNAL</ANIM>
        </UseInputEvent>
        <UseTemplate Name="ASOBO_GT_MouseRect"> <!-- Interaction -->
            <TOOLTIP_ENTRY_0>INSTRUMENT_#BTN_ID#</TOOLTIP_ENTRY_0>
            <MOUSEFLAGS>Lock+LeftSingle</MOUSEFLAGS>
            <CURSOR>Hand</CURSOR>
            <CALLBACKCODE>
                (M:Event) 'LeftSingle' scmp 0 == if{
                    (B:INSTRUMENT_#BTN_ID#) ! (&gt;B:INSTRUMENT_#BTN_ID#_Set)
                }
                1 (&gt;O:_ButtonAnimVar)
            </CALLBACKCODE>
        </UseTemplate>
        <UseTemplate Name="ASOBO_GT_Update"> <!-- Update to reset anim -->
            <FREQUENCY>10</FREQUENCY>
            <UPDATE_CODE>
                (O:_ButtonAnimVar) 0 &gt; if{
                   (O:_ButtonAnimVar) 0.2 - (&gt;O:_ButtonAnimVar)
                }
            </UPDATE_CODE>
        </UseTemplate>
    </Component>
</Template>

Note that if you need to do something very specific with your Input Event, it is possible to implement a 100% custom Input Event rather than relying on the generic Input Event and generic template (used above). However it is generally not necessary or useful.

 

Interaction Template Using A Complex Template

You can create your own interaction template with multiple, complex interactions by making use of some of the supplied templates listed here: Generic Complex Templates. These templates will handle most of the logic that causes the interaction to behave like a Switch/Push button/Knob/etc... depending on which Complex template you use.

 

This example shows a custom template using the Complex template components:

<Template Name="MyPushButton">
    <Parameters Type="Default">
        <NODE_ID>MyNode</NODE_ID>
        <ANIM_NAME>MyAnim</ANIM_NAME>
        <TOOLTIP_TITLE>@TT_MyAircraft.NAME_OF_MY_TT_TITLE</TOOLTIP_TITLE>
        <TT_DESCRIPTION_ID>@TT_MyAircraft.NAME_OF_MY_TT_ACTION</TT_DESCRIPTION_ID>
    </Parameters>
    <Parameters Type="Override">
        <BTN_ID>MyIEName</BTN_ID><!-- Name of the Input Event -->
        <IS_ON>(O:MyVar)</IS_ON><!-- This Param is used as a shorthand below -->
    </Parameters>
    <Component ID="#NODE_ID#" Node="#NODE_ID#">
        <Parameters Type="Override">
            <TOOLTIP_ENTRY_0>INSTRUMENT_#BTN_ID#</TOOLTIP_ENTRY_0>
        </Parameters>
        <UseInputEvent ID="INSTRUMENT">
            <SET_STATE_EXTERNAL>#IS_ON# p0 != if{ p0 (&gt;O:MyVar) }</SET_STATE_EXTERNAL>
            <GET_STATE_EXTERNAL>#IS_ON# sp0</GET_STATE_EXTERNAL>
            <SIM_STATE_IS_ON_EXTERNAL>l0</SIM_STATE_IS_ON_EXTERNAL>
            <ANIM>EXTERNAL</ANIM>
        </UseInputEvent>
        <UseTemplate Name="ASOBO_GT_Push_Button">
            <LEFT_SINGLE_CODE>(&gt;B:INSTRUMENT_#BTN_ID#_Toggle)</LEFT_SINGLE_CODE>
        </UseTemplate>
    </Component>
</Template>

 

Interaction Template Using A Base Template

Of all possible solutions to dealing with interactions, the best is almost always to use a Base Template, such as ASOBO_INSTRUMENT_Base_Template. Base template are templates that will automatically create the animation, interaction, input event and audio based on the parameters that are provided.

 

This example shows a custom template made using Base templates:

<Template Name="MyPushButton">
    <Parameters Type="Default">
        <NODE_ID>MyNode</NODE_ID>
        <ANIM_NAME>MyAnim</ANIM_NAME>
        <TOOLTIP_TITLE>@TT_MyAircraft.NAME_OF_MY_TT_TITLE</TOOLTIP_TITLE>
        <TT_DESCRIPTION_ID>@TT_MyAircraft.NAME_OF_MY_TT_ACTION</TT_DESCRIPTION_ID>
    </Parameters>
    <Parameters Type="Override">
        <BTN_ID>MyIEName</BTN_ID><!-- Name of the Input Event -->
        <IS_ON>(O:MyVar)</IS_ON><!-- This Param is used as a shorthand below -->
        <INTERACTION_TYPE>Push</INTERACTION_TYPE>
    </Parameters>
    <UseTemplate Name="ASOBO_INSTRUMENT_Base_Template">
        <IE_NAME>#BTN_ID#</IE_NAME>
        <!-- p0 == 1 when pushed -->
        <SET_STATE_EXTERNAL>#IS_ON# p0 != if{ p0 (&gt;O:MyVar) }</SET_STATE_EXTERNAL>
        <GET_STATE_EXTERNAL>#IS_ON# sp0</GET_STATE_EXTERNAL>
    </UseTemplate>
</Template>