Define instruction

Repetitive SDL fragments can be described using the define instruction for further multiple calls in the required places.

Template for the define instruction

Template for the define instruction

(define "name" [code])
  • "name" - the identifier for the define instruction, enclosed in double quotes.

  • [code] - an optional SDL fragment that will be inserted wherever the define is called.

The parentheses (...)are mandatory and encapsulate the entire instruction, ensuring that the parser SDL recognizes and correctly processes the definition as a single cohesive unit.

Arguments in a define instruction

The SDL fragment can contain arguments, the values of which usually change from one call to another.

Example of a define instruction without arguments
(define "seismic_custom"
    {damage seismic {energy 10} {radius 8}}
)
Example of a define instruction with numeral arguments
(define "seismic_custom"
    {damage seismic {energy %0} {radius %1}}
)
Example of a define instruction with named arguments
(define "seismic_custom"
    {damage seismic {energy %energy} {radius %radius}}
)

Calling a define instruction

The define instruction is called by its name, which is enclosed in double quotes.

Template for calling a define instruction

("name" [args])
  • [args] - arguments are optional

When calling a define instruction that does not require arguments, you simply use the name of the defined term within the SDL script where you need the defined contents to appear. The syntax is straightforward; since no arguments are involved, you only need to reference the defined name within double quotes.

Example of calling a define instruction without arguments

Source SDL fragment:

(define "seismic_custom” 
    {damage blast 
        {energy 10}
        {radius 8}
    }
)
...
(“seismic_custom”)

In this example, whenever "seismic_custom" is used in the SDL script, it will insert the set of commands defined under “seismic_custom”description. Since no arguments are used, you don't need to enclose anything other than the double-quoted name in parentheses.

Result SDL fragment:

...
{damage blast 
        {energy 10}
        {radius 8}
}
...
Example of calling a define instruction with ordinal arguments
(define "seismic" 
    {damage blast 
        {energy %1}
        {radius %0}
        {light %2}
    }
)
...
("seismic" args 10 8 3000)
...
("seismic" args 45 300 3000)

At the first call of the "seismic" instruction, the arguments take the following values: %0=10, %1=8, %2=3000 At the second call of the "seismic" instruction, the arguments take the values: %0=45, %1=300, %2=3000 The result of the "seismic" instruction call will be SDL, containing at the call sites the lines:

...
{damage blast 
     {energy 8}
     {radius 10} 
     {light 3000}
}
...
{damage blast 
     {energy 300}
     {radius 45} 
     {light 3000}
}
Example of calling a define instruction with named arguments
(define "seismic" 
    {damage blast 
        {energy %energy} 
        {radius %radius}
    }
)
...
("seismic" energy(10) radius(8))
...
("seismic" radius(300) energy(45))

The result of the "seismic" instruction call will be SDL, containing at the call sites the lines:

...
{damage blast 
     {energy 10}
     {radius 8} 
}
...
{damage blast 
     {energy 45}
     {radius 300}
}

When calling the instruction, values for named arguments may be empty.

Example of calling a define instruction with an empty argument

Source SDL:

(define "seismic" 
    {damage blast 
        {energy %energy} 
        {radius %radius}
    }
)
...
(“seismic” energy() radius(8))

Result SDL:

...
{damage blast 
        {energy  } 
        {radius 8}
}

Nested define instruction

Nested define instructions allow you to build complex configurations by combining simpler defined components into more sophisticated structures. Here's how you can define and use nested define instructions in SDL

  1. Defining basic components

Define some basic components that we'll use in our nested setup.

Example
(define "AmbientLight" {light_intensity 1.0})
(define "SetBackgroundColor" {background_color "blue"})
  1. Creating a nested define instruction

Next, you can define a more comprehensive setup that includes these previously defined components. This is where the nesting comes into play.

Example of a nested define instruction
(define "StandardSceneSetup" 
    ("AmbientLight")
    ("SetBackgroundColor")
    [code]
)

In this nested define, "StandardSceneSetup" calls both "AmbientLight" and "SetBackgroundColor" within its definition.

  1. Calling a nested define instruction

Finally, you use the nested definition in your SDL script where needed, just like any other defined instruction

Example of calling a nested define instruction
("StandardSceneSetup")

Calling the "StandardSceneSetup" will execute all the commands in "StandardSceneSetup", including the nested definitions of "AmbientLight" and "SetBackgroundColor", along with any additional commands defined directly within "StandardSceneSetup"

Result SDL:

...
{light_intensity 1.0}
{background_color "blue"}
[code]
...

Benefits of nested define instructions

  • Modularity You can create modular blocks of SDL that can be reused and combined in various ways.

  • Maintainability It’s easier to update and maintain your SDL scripts, as changes to a single defined block will propagate wherever it is used.

  • Clarity Nested definitions can help clarify the structure of complex setups by breaking them down into manageable parts.

Nested define instructions thus provide a powerful way to structure and simplify complex SDL configurations in a scalable and maintainable manner.

Using arguments as a part of a define instruction name

Using arguments as a part of define instruction name can offer several benefits in scripting:

  • to create generic instructions that dynamically call relevant content definitions based on the arguments passed;

  • to reduce a code duplication;

  • to disable one or several nested instructions if it is necessary

The empty define instructions are used when it is necessary to disable one or several nested instructions. In this case, an argument is often used in the name of the nested instruction when calling.

Example of using an empty define instruction
(define "content_none")
(define "content_v" {content data1})
(define "content_v_officer" {content data2})
(define "set_default" ("content_%con"))
...
("set_default" con(none))
("set_default" con(v) )
("set_default" con(v_officer))

In this example, we are dealing with dynamically selecting and invoking specific content definitions based on arguments provided to a define instruction.

  • "content_none" is an empty definition, used when no content is necessary.

  • "content_v" and "content_v_officer" include specific data content (data1 and data2 respectively).

  • "set_default" demonstrates a dynamic content selection mechanism using the argument %con. This setup allows the set_default instruction to dynamically call one of the content definitions based on the suffix provided.

  • The calls to "set_default" pass different arguments (none, v, and v_officer) to the %con argument, determining which of the "content_*" definitions is executed. For instance, ("set_default" con(none)) will call "content_none".

More examples

An alternative name for the define instruction is macro.

Example of a basic macro with a basic set of parameters
(define "set_generic"
  {charge %ch}
  ("score" sc(%sc))
  {tags "%tag %side"}
  ("cw_%cw")
  {cp %cp}
  {level %lvl}
  {cost 0}
  {fore 1}
)
Example of a macro with a standard set of settings
(define "set_default"
    ("content_%con" side(%side) n(%n))
    ("set_generic" ch(%ch) sc(%sc) tag(%tag) side(%side) cw(%cw) cp(%cp) lvl(%lvl))
    ("spawn_distance_%sd")
    ("territory_holder_%th")
)
Example of a top-level macro that uses standard settings
(define "set_v" ("set_default" con(v) ch(0) sc(%sc) tag(%tag) side(%side) n(%n) cw(%cw) cp(%cp) lvl(%lvl) sd(default) th(%th)))

The result of calling the set_v instruction will be the final setting for the PZ1b

{"pz1b" ("set_v" 
        lvl(1) 
        tag(all tnk_light level_1) 
        side(ger) 
        n(2) 
        sc(10) 
        cw(s2) 
        cp(3) 
        th(tanks)
    )
}

If you have difficulties understanding the terminology and the essence of the instruction description, please refer to the article Basic knowledge about configuration files.

Additionally, you can explore other types of instructions.

Last updated