Warning:

This guide assumes intermediate to near complete mastery of basic XML editing/modding in SimplePlanes. If you are not familiar with XML editing yet, proceed at your own risk. The following guide is considerably long and certain sections are still under construction.

Introduction: What is Funky Trees?


First implemented in game version 1.9, Funky Trees is a special subset of XML editing/modding in SimplePlanes that specifically deals with the group, activationGroup, and input attributes of parts. By nature, Funky Trees is a special subfield of what's known as XML editing/modding in SimplePlanes. Difficulty with basic XML editing may prove detrimental to learning the Funky Trees system.

To be more specific, when an user does things in SimplePlanes, like controlling an aircraft by moving the joystick or pressing the keyboard, essentially what's being done is that the user is sending a signal to the various functional components on the craft to move it as the user intends it to. Funky Trees expands the options here and allows for much more complex programming of the inputs to allow for very special input programming to allow creation of incredibly powerful and useful parts.

For example, users have created parts that carry out complex actions that weren't possible before 1.9, such as functional all-altitude bombsights, the first functionally complete chronographs, and automatic flight control systems. As it stands, Funky Trees can be considered a very specifically designed programming language- it fufills the definition of one.

For a new learner, it is strongly recommended that the document be read in its full length, in chronological order. This particular guide is primarily tailored to help the learning of newer learners.


Prerequisites: Things you probably should know


Funky Trees isn't some entirely new field of study, but given the broad expanse of what it covers, the following concepts are recommended for full mastery of Funky Trees capability. These come in no particular order, there is no need for you to master all of them, but to use everything in Funky Trees, you must know all of these concepts.

  • XML Modding*
  • Algebra*
  • Calculus Concepts
  • Programming/CS

* indicates required fields of knowledge. Usage of calculus is largely limited to a couple of functions, but is still quite useful to know. Programming/CS knowledge is extremely useful to know when structuring Funky Tree inputs (FT is practically a programming language) and will help in understanding FT in general, but is not necessary.


Section 1: Syntax and Semantics


Not unlike other conventional programming languages, Funky Trees utilizes a system of inputs and outputs. It takes various inputs, processes them, and relays an output that is then taken by the part (whatever "part" you're putting FT inputs into) to result in some kind of of behavior by the part.

By the same token, Funky Trees follows a set of predefined rules to make the system work. This is commonly known as "syntax". There aren't a large number of rules in Funky Trees- they can be generalized to the following:

  • Spelling matters, including spacing (see "semantics")
  • Capitalization matters: Hello and hello are two very different things
  • Mathematical operations in Funky Trees follows standard order of operations (see "operators")
  • One small error leads to the entire expression not evaluating / evaluating incorrectly. Often this may be the case for complicated input expressions that yield errors.

Another common idea from programming comes into play in Funky Trees- when a certain, specifc order of symbols a grouped together in a very specifc way, they can hold meaning in the eyes of the system. This is commonly known as "semantics". For example, in the eyes of Funky Trees, the expression altitude has no meaning to the system. However, the expression Altitude has a very specifc value and meaning to the system, and the expression will evaluate accordingly. If these "very specifc combinations of symbols" are likened to functional "elements", it is possible to categorize these elements into to one of three categories. They are:

  1. Variables
  2. Functions
  3. Operators

The following sections elaborate on these three categories in great detail, just after the data types section.


Section 2: Data Types


To give an input to the part, you probably need some sort of data to work with, right? Since version 1.9.2, Funky Trees was revamped to have data type organization. To explain, all usable data types in Funky Trees have now been organized into one of three categories- numbers, booleans, and strings. Here’s a rundown:

  • Numbers are numbers including floats (e.g. 1, 1314, 12.0003, 0.334, etc).
  • Booleans are very useful for logic. They are either true, or false. If you use them in conjunction with other data types, true or false can output the numbers 1 or -1 respectively. Previously, before 1.9.2, booleans were inconsistent, this now has been fixed to be much more predictable.
  • Strings are basically lines of text. They must be enclosed in quotations (“” marks) (e.g. "Text").

Hopefully, this made sense. If you're new to computer science, these terms may sound completely alien to you- but don't worry, it'll make sense in due time (this is the only reason why programming experience comes in handy, to help orient yourself quicker).


Section 2A: Variables


I first want to make sure that you understand what variables are in Funky Trees. Variables are special words that have a special value in Funky Trees. They contain data. The data type organization, in other words, is a way of organizing these variables into different types. The following is a list of all input variables. Don't panic, this is simply for reference.

Pitch Roll Yaw Throttle Brake
Trim VTOL LandingGear GearDown FireGuns
FireWeapons LaunchCountermeasures Activate1 Activate2 Activate3
Activate4 Activate5 Activate6 Activate7 Activate8
Altitude AltitudeAgl GS IAS TAS
Fuel AngleOfAttack AngleOfSlip PitchAngle RollAngle
Heading Time GForce VerticalG SelectedWeapon
Latitude Longitude PitchRate RollRate YawRate
TargetSelected TargetHeading TargetElevation TargetDistance

We can now categorize these variables based on their data category (their possible values included in parentheses).


  1. 1. Number-type Variables


    By far the most numerous, the numbers datatype contains variables that equate to the number class of variables. They’re conceptually easy to manipulate, but there are a great variety of number type variables and each has a unique range of values. TL;DR: simply numbers, but everything is unique (requiring special attention from you). The following is a list of all number type variables and their possible values.

    Variable Variable Description Range of Values
    Pitch The amount of Pitch input as a proportion (-1, 0, 1) / alternatively (-1~1) if joystick
    Roll The amount of Roll input as a proportion (-1, 0, 1) / alternatively (-1~1) if joystick
    Yaw The amount of Yaw input as a proportion (-1, 0, 1) / alternatively (-1~1) if joystick
    Trim The amount of Trim input as a proportion (-1~1)
    VTOL The amount of VTOL input as a proportion (-1~1)
    Throttle The amount of Throttle input as a proportion (0~1)
    Altitude Aircraft's altitude in meters (-inf~inf)
    AltitudeAgl Aircraft's altitude above ground level in meters (-inf~inf)
    GS he speed relative to the ground (m/s) (0~inf)
    IAS The speed relative to the air (m/s) (0~inf)
    TAS The speed relative to the air, adjusted for the density of the air (m/s) (0~inf)
    Fuel The amount of fuel remaining as a proportion of capacity (0~1)
    AngleOfAttack The angle of attack (angle airflow vertically meets the boresight) in degrees (-180~180)
    AngleOfSlip The horizontal equivalent of angle of attack (degrees) (-180~180)
    PitchAngle The pitch of the aircraft (degrees) (-90~90)
    RollAngle The roll of the aircraft (degrees) (-180~180)
    Heading The heading of the aircraft (degrees) (-180~180)
    Time The time since the level loaded (seconds) (0~inf)
    GForce (omnidirectional "force" acting on the pilot, in g) (0~inf)
    VerticalG G-force (vertical component of G-force) (0~inf)
    Latitude The y-position of the craft in the sandbox map (-inf~inf)
    Longitude The x-position of the craft in the sandbox map (-inf~inf)
    PitchRate The rate at which the aircraft pitches (deg/s) (-inf~inf)
    RollRate The rate at which the aircraft rolls (deg/s) (-inf~inf)
    YawRate The rate at which the aricraft yaws (deg/s) (-inf~inf)
    LandingGear Archaic FT input type. Use GearDown instead when making FT inputs. (0, 1)
    TargetHeading Returns the heading of the selected target, relative to the position of your cockpit, in bearing (degrees). Note that this is global, meaning that it is not relative to your current heading. View an explanatory diagram here. (0~360)
    TargetElevation Returns the line-of-sight angle to the selected target, relative to the position of your cockpit, in degrees. Note that this is global, meaning that it is not relative to your PitchAngle. View an explanatory diagram here. (-90~90)
    TargetDistance Returns the line-of-sight distance to the selected target, relative to the position of your cockpit, in meters. (0~inf)

  2. 2. Boolean-type Variables


    Booleans were previously inconsistent in Funky Trees due to a couple errors. The system has been revamped completely, removing the root source of that error. Now, if you only use boolean statements independent of other data types, you will get the value true or false. If you use booleans in conjunction with the number data type, they will automatically convert to 1 or -1 (true or false respectively). That also means, in the table down below, all the booleans can also be considered to have a possible range of values of -1 or 1. TL;DR: All boolean data type variables return either true or false, or 1 or -1 depending on its usage. This makes these logically consistent. The following is a list of all number type variables and their possible values.

    Variable Variable Description Range of Values
    Brake Whether or not Brake is pressed true / false
    GearDown Whether or not landing gear is on or off true / false
    FireGuns Whether or not guns button is pressed true / false
    FireWeapons Whether or not fire ordnance button is pressed true / false
    LaunchCountermeasures Whether or not launch countermeasures button is pressed true / false
    Activate1 Whether or not activation group 1 is on true / false
    Activate2 Whether or not activation group 2 is on true / false
    Activate3 Whether or not activation group 3 is on true / false
    Activate4 Whether or not activation group 4 is on true / false
    Activate5 Whether or not activation group 5 is on true / false
    Activate6 Whether or not activation group 6 is on true / false
    Activate7 Whether or not activation group 7 is on true / false
    Activate8 Whether or not activation group 8 is on true / false
    TargetSelected Whether or not a target is selected true / false
  3. 3. String-type Variables


    Simply put, strings are just lines of text, like "text". The number of actual strings datatype variables is technically only one as of the time of writing. However, whatever you make your string- be it “this string” or “that string”- are all valid strings. Strings don't really have a large variety of applications right now, but they can be useful.

    Variable Variable Description
    SelectedWeapon Outputs the name of the selected weapon in the weapons drawer as a string, e.g. "Boom 50", "Cannon"

Section 2B: Functions


Now is the time to jog your brain for actual school math: remember functions? All that f(x) and g(x) and stuff? Well, now it's in SimplePlanes, and you can use it to do cool stuff. Functions are special objects that take in inputs and return an output, each depending on what the function does. Functions, in Funky Trees, are designed like so:

function(input)

Functions are defined to the system by the function name- in the example, the word 'function'. Functions also have one more crucial attribute: they also have an 'input' within the parentheses following the function name. Some functions take more than one input, for example, the clamp function takes inputs in the form of clamp(x, a, b). Functions can only take specific datatypes as inputs (which is why I previously covered the data types)- there are functions that only accept string-type data as inputs, like the ammo function. The following is a list of all available functions as of game version 1.9.205. The following is simply for reference.

abs() ceil() clamp() deltaangle() exp() floor() inverselerp() lerp() lerpangle() lerpunclamped()
log() log10() pingpong() max() min() pow() repeat() round() sign() smoothstep()
sqrt() sin() cos() tan() asin() acos() atan() rate() sum() smooth()
PID() ammo()

Moreover, each function acts in unique ways, which is how they are classified in the following few subsections.


  1. 1. Number-based Functions


    Number based functions are the most conceptually simple. It takes inputs that would be classified under the ‘number’ data type, and outputs a ‘number’ data type. However, if you recall Section 2A, it was mentioned that booleans can be converted to a number of 1 or -1 (true or false)- this means that number based functions can take boolean inputs, but note that the number function is taking not the boolean themselves as input, but only the number-converted boolean. A number function will not take a string input, like the string "thisstring". They will also only ouput a number, i.e. a number function might take the value 1 and output 0.2.

    The following table organizes all the number based functions, their input syntax, and their usage.

    Function Name/Syntax Usage
    abs(x) The absolute (positive) value of x.
    ceil(x) x rounded up to an integer.
    clamp(x, min, max) x clamped between min and max.
    clamp01(x) x clamped between 0 and 1. Equivalent to clamp(x, 0, 1)
    deltaangle(a, b) The smallest angle delta between angles a and b in degrees.
    exp(x) Returns e raised to the power of x.
    floor(x) x rounded down to an integer.
    inverselerp(a, b, x) Calculates the linear parameter t that produces the interpolant value within the range [a, b].
    lerp(a, b, t) Linearly interpolates between a and b, by a proportion of t.
    lerpangle(a, b, t) Similar to lerp, but interpolates correctly when values pass 360 degrees.
    lerpunclamped(a, b, t) Similar to lerp, but doesn't clamp the value between a and b.
    log(x, p) The logarithm of x in base p.
    log10(x) Equivalent to log(x, 10).
    pingpong(x, l) "Ping-pongs" the value x so it is never larger than l and never less than 0.
    max(a, b) The largest value between a and b.
    min(a, b) The smallest value between a and b.
    pow(x, p) x raised to the power of p.
    repeat(x, l) Loops the value x so it is never larger than l and never less than 0.
    round(x) Rounds x to the nearest integer.
    sign(x) The sign of x (1 if x positive, -1 if x negative)
    smoothstep(a, b, t) Similar to lerp, but with smoothing at the ends.
    sqrt(x) The square root of x.
    sin(x) The sine of x (degrees)
    cos(x) The cosine of x (degrees)
    tan(x) The tangent of x (degrees)
    asin(x) The arc-sine of x (degrees)
    acos(x) The arc-cosine of x (degrees)
    atan(x) The arc-tangent of x (degrees)
  2. 2. Time-based Functions


    These functions were added in game version 1.9.2. These are functions that measure things with respect to time. In particular, the rate and sum functions are the FT equivalent of derivatives (d/dx) and integrals (∫dx), which enables the creation of far advanced inputs. These functions can be greatly useful but most things can be done without them, so do not fret- if your math is on the level to understand derivatives and integrals, then you don’t really need much explanation on what these will do. We're not working with variable expressions, so more of the academic calculus like the power rule is pretty much useless- you will really only be utilizing the practical application of them.

    Function Name/Syntax Usage
    rate(x) The rate of change of x.
    sum(x) The integration of x over time. Time starts from level load (no integration bounds can be specified).
    smooth(x, rate) The output follows x, but only at a maximum speed of rate units per second.
    PID(target, current, p, i, d) A PID controller with the parameters p, i and d. Read more about PID controllers on Wikipedia. Learn a quick beginner's guide on tuning PIDs.

  3. 3. String-based Functions


    There’s currently only one string-based function as of version 1.1.104- it’s the ammo() function. Since it takes a string as input, that also means that the input the ammo function can be a string-type variable- i.e. the SelectedWeapon variable.

    Function Name/Syntax Usage
    ammo("string") The amount of ammo left for the weapon “someweaponname”. That is, whatever the name of your weapon is, is the string you want to input into “string”, to which the function will return the amount of remaining ammo.

Section 3: Operators


The Funky Trees system offers a variety of operators to use within input expressions. Simply put, operators are symbols indicating a mathematical operation. There are two types of operators in Funky Trees:

  1. Math Operators
  2. Logic Operators

Refer to the following two sections for information on each.


  • A. Math Operators


    Math operators are conceptually very simple. They perform basic algebraic calculations. The following table lists all available math operators, their usage, and examples. Take a, b, c as other expressions or constants.

    Symbol Usage Example Explanation
    + Addition a + b Yields the value a + b. While spaces may not be required, sometimes no spacing can cause errors. For the sake of consistency, it is highly advised you put single spaces around the operator. Additionally, strings can be concatenated through the addition operator. For example, the statement "He" + "llo" will yield the resulting string "Hello".
    - Subtraction or Negative sign a - b or -c Yields the value a - b. While spaces may not be required, sometimes no spacing can cause errors. For the sake of consistency, it is highly advised you put single spaces around the operator.
    * Multiplication a * b Yield the value a * b. While spaces may not be required, sometimes no spacing can cause errors. For the sake of consistency, it is highly advised you put single spaces around the operator.
    / Division a / b Yield the value a / b. While spaces may not be required, sometimes no spacing can cause errors. For the sake of consistency, it is highly advised you put single spaces around the operator.
    () Parentheses to group statements (a + b) * c Groups statements. In this example, the operation a + b is done before c is multiplied. Note: implied multiplication, like in the form of (a)(b), is not supported. To do this, you must use the multiplication operator.

    To illustrate the math operators in context, here's an example: assume that the value of the variable, Roll, is set to 1 because the positive roll button is pressed. If a final value of 5 is desired, adding 4 to the current Roll value will yield 5. Therefore the expression Roll + 4 would evaluate (result) in: (+1) + (+4) == (+5). All of the math operators are used in similar fashion to the example illustrated.


  • B. Logic Operators


    Logic operators are conceptually more abstract, as they rely on boolean logic instead of simple algebra. They always output a boolean value as the ouput- either true or false. There are three types of operators- comparison, boolean, and selection operators. Each is explained below. For some operators, a truth table is also included for reference.


    • 1. Comparison Operators


      Comparison operators are very conceptually simple. They compare the two values on each side of the operator and output the result as a boolean. Comparison operators only take numbers as input (or number-converted booleans).

      Comparison Operators List
      This operator can take numerical input. This operator can take numerical input.
      Symbol Usage Example Explanation
      = Equality a = b Checks if a = b. If a is equal to b, the output will be true. In any other case, it will be false.
      != Nonequality (NOT) a != b Checks if a != b. If a is NOT equal to b, the output will be true. In any other case, it will be false.
      > Greater than a > b Checks if a > b. If a is greater than b, the output will be true. In any other case, it will be false.
      < Less than a < b Checks if a < b. If a is less than b, the output will be true. In any other case, it will be false.
      >= Greater than or equal to a >= b Checks if a >= b. If a is greater than, or equal to b, the output will be true. In any other case, it will be false.
      <= Less than or equal to a <= b Checks if a <= b. If a is less than, or equal to b, the output will be true. In any other case, it will be false.

    • 2. Boolean Operators


      Boolean, or logic operators operate based on booleans, that is, the values true or false. This also means they only take boolean operands.

      Boolean Operators List
      Symbol Usage Example Explanation
      & Boolean AND a & b Checks if both a and b are true. If any one of the two operands are false, the expression will output false.
      | Boolean OR a | b Checks if either one of a and b are true. If any one of the two operands are true, expression will output true. This operator only ouputs false if both operands are false.
      ! Boolean Invert !a This operator inverts the value of a boolean. That is, !true is false, and !false is true. This effectively is the same as doing -a, where a is a boolean, but only works for unary (booleans), while - (the negative sign) can work on both unary and binary (booleans and numbers).

    • 3. Selection Operators


      Selection operators output one of the two expressions as output depending on the value of the initial condition.

      Selection Operators List
      Symbol Usage Example Explanation
      ? : IF (ternary selection) a ? b : c Checks if a is true or false. If a is true, the operator outputs the value b. If a is false, the operator outputs the value c. This also means the selection operator can have a variety of types of outputs (but a must be a boolean value).
    Notes

    Once again, it is worth noting that the boolean operators take only boolean operands. To generate a boolean, the standard comparison operators must be utliized.


Section 4: Practical Input


The first three sections of this guide provides apt commentary / explanation on the theoretical aspect of Funky Trees. However, the practical aspect of designing and programming a Funky Trees input has yet to be discussed; as such, this section will discuss practical implementation of Funky Trees inputs. Specifcally, this section deals with actual writing of inputs, as many struggle with this. As with any other XML editing, there are two approaches to editing the XML file of a creation. One is using inbuilt Overload XML editor (cross-platform) or using a text editor to directly edit XML files. Either approach allows for the same kind of editing, although for mass edits a search-replace function that comes inbuilt with most text editors may be far more preferable.


Compatability

Funky Trees inputs are compatible with three types of attributes within XML editing: the input attribute within the inputController class of attributes, and the activationGroup and group attributes for certain parts. The behavior of Funky Trees in each of these is different, which warrants an explanation.

  • A. input Attribute


    The input attribute is usually the primary application of Funky Trees. Most gizmo-type parts and propulsion-type parts contain an inputController class of attributes that contains the input attribute. The following image is an example of an input attribute Overload window.


    Note the highlighted sections. The under the inputController class, the input attribute is visible, with the value of the input attribute on the side. In the example, the input is Throttle. A Funky Trees expression can be entered here. The behavior of parts is unique for each part- an input will simply determine the degree to which an part responds. It is the fine-tuning and programming of these "degree of response" that Funky Trees is concerned with, producing very useful and special behavior.

  • B. activationGroup / group Attributes


    The activationGroup attributes are usually of lesser importance for Funky Trees (but can prove to be useful). Practially all parts, aside from structural parts like fuselage blocks, contain an activationGroup attribute, typcially contained under inputController classes or part-specifc classes. The following image is an example of an activationGroup attribute Overload window.


    Note the highlighted sections. For the example, under the Magnet class (a part-specifc class), the activationGroup attribute is visible, with the value of the activationGroup attribute on the side. In the example, the value is 1. A Funky Trees expression can be entered here.

    The group attribute is practically the same as activationGroup, but only applies for certain types of types like detachers. The following image is an example of an activationGroup attribute Overload window.


    Note the highlighted sections. For the example, under the Detacher class (a part-specifc class), the group attribute is visible, with the value of the group attribute on the side. In the example, the value is 1. A Funky Trees expression can be entered here.

    The difference in response to Funky Trees defines the difference between input attributes and activationGroup / group attributes. For input attributes, the behavior of parts simply depends on the numerical value of the input. However, for activationGroup and group attributes, the behavior is a boolean (true / false, on / off), defined by the value of the FT expression being larger than 0. For example, for a detacher with some FT expression, the detacher will activate / fire the moment the FT expression in it returns a value larger than 0. For this reason, it may be largely preferable to have FT expressions for the activationGroup and group attributes be based on booleans instead of mathematical systems.


Section 5: Miscellaneous & Tools


Sections 1 to 4 cover practically all that can be taught in the realm of the Funky Trees system. The actual formulation of actual Funky Trees expressions largely depend on the creator's own ability to manipulate these features included in the Funky Trees package- studying expressions by other creators may help apply the same style of patterns to one's own. Additionally, there also exist standardized/generalized FT expression for specifc purposes, which may be helpful to the common creator. A full index of commonly used general Funky Trees expressions can be found in the commonly used FT expressions page (currently under construction). This final fifth section covers other tools that can assist in forming FT programs.

  1. A. Console Debugger


    Whilst creating FT expressions, especially for longer, more complicated expressions, it may be desirable to be able to obtain an live readout of the actual values of expressions. Using the inbuilt game console, accessed using the ` key on PC platforms and three finger taps on mobile platforms, a debugger console is available to debugging FT expressions. Type the following command into the console:

    DebugExpression "expression"

    Where expression is the FT expression you are attempting to debug. This can be used with any FT expression- however, for FT expressions that contain quotation marks ("") (for string values), the quotation marks inside the FT expression must be replaced with sharp marks (##). This is to avoid issues with confusing the console.

    Once the DebugExpression command is used, a small window will appear on the top left corner of the screen displaying your entered expression, and also the value of the expression aside a colon mark :.

    To clear the debugger console, enter the command ClearDebugExpressions into the console.

  2. B. Code Editor


    When writing Funky Trees code, you may find that it is quite difficult to actually make sense of what you're writing, especially in terms of code structure and trying to figure out if you have the right number of parentheses in the expression. Sometimes you want to stop writing the same variable name over and over again. Or you just might want a good text editor, especially for programming.

    Atom is a great open source software that does everything you really need for funky trees. It has a parentheses highlighting function that helps you figure out pairings, word autofill for variables that you are repeatedly using, and a lot more that can help you do funky trees easier. Of course, Notepad or TextEdit is fine, but Atom is a great software that just makes life easier. You can also custom-code extensions that do things for you.