Profile image

Funky Trees!

Dev WNP78  4.4 years ago

Andrew decided to call the new inputs system I cooked up "funky trees". Somehow escapes me why, but I'll roll with it. Here I'll describe what you can do in the land of funk.


Essentially what this means is that you can enter any mathematical expression (following this syntax) into an input field and it will be evaluated every frame. You can pull in data from a variety of sources, and process these how you like.

Inputs

What you can now do is use the normal input axes:

  • Pitch
  • Roll
  • Yaw
  • Throttle
  • Brake
  • Trim
  • VTOL
  • LandingGear
  • FireGuns
  • FireWeapons
  • LaunchCountermeasures
  • Activate1
  • Activate2
  • Activate3
  • Activate4
  • Activate5
  • Activate6
  • Activate7
  • Activate8

Flight data

In addition to this you can access some information from the aircraft:

  • Altitude - Aircraft's altitude in metres
  • AltitudeAgl - Aircraft's altitude above ground level in metres
  • GS - The speed relative to the ground (m/s)
  • IAS - The speed relative to the air, adjusted for the desnity of the air (m/s)
  • TAS - The speed relative to the air (m/s)
  • Fuel - The amount of fuel remaining as a proportion of capacity (0 to 1)
  • AngleOfAttack - The angle of attack (angle airflow vertically meets the boresight) in degrees
  • AngleOfSlip - The horizontal equivalent of angle of attack (degrees)
  • PitchAngle - The pitch of the aircraft (degrees)
  • RollAngle - The roll of the aircraft (degrees)
  • Heading - The heading of the aircraft (degrees)
  • Time - The time since the level loaded (seconds)
  • GForce - The acceleration and gravitational "force" acting on the cockpit in G. I know it's not a force. Shut up.
  • VerticalG - The signed vertical component of the "G Force".
  • SelectedWeaponName - The name of the selected weapon
  • Latitude - The North/South position of the craft (metres)
  • Longitude - The East/West position of the craft (metres)
  • PitchRate - The pitch angular velocity in degrees/second
  • YawRate - The yaw angular velocity in degrees/second
  • RollRate - The roll angular velocity in degrees/second (these 3 inputs are better than using rate(PitchAngle) etc, because they account for wrapping around the angle, as well as being in local space: rate(Heading) is different to YawRate)
  • TargetSelected - true if a target is selected, else false.
  • TargetHeading - the heading to the selected target in degrees.
  • TargetElevation - the vertical angle to the selected target in degrees.
  • TargetDistance - the distance to the selected target in metres.

Constants

Values that are always the same:

  • pi the mathematical constant pi (half a tau, if you will).
  • e the mathematical constant e.
  • true a true boolean value
  • false a false boolean value

Operators

These are useful for... maths or something.

  • Mathematical:

    • +, - addition and subtraction (- can be used as a unary operator, for instance -Pitch

    • *, / multiplication and division

  • Comparison:

    • <, > less than, greater than

    • <=, >= less than or equal to, greater than or equal to

    • ==, != equal to, not equal to

  • Boolean:

    • &, AND

    • |, OR

    • !, NOT (this is a unary operator)

    • Ternary operator: condition ? value_if_true : value_if_false - this chooses between two values based on the condition.

Functions

Finally, there's some helpful functions to do maths for you!

  • abs(x) - The absolute (positive) value of x.
  • ammo(name) - The amount of ammo of the weapon with name. Remember to put the name in " quotes.
  • ceil(x) - x rounded up to an integer.
  • clamp(x, min, max) - x clamped between min and max.
  • clamp01(x) - Equivalent to clamp(x, 0, 1).
  • deltaangle(a, b) - The shortest 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)
  • atan2(y, x) - The angle in degrees whose tangent is y/x. In other words the angle (argument) of a vector

Memory Functions

These are functions that are special because their output not only depends on inputs but their previous state.
- sum(x) - Returns the sum of all it's inputs over time (the integral of x)
- rate(x) - Returns the rate of change of x relative to its value last frame (the derivative of x)
- smooth(x, t) - When loaded, it's output is set to x. As x changes, the output tries to move to x, but at a rate of no greater than t. This is vaguely equivalent to changing the speed of a rotator.
- PID(target, current, p, i , d) - Evaluates a PID controller with the setpoint of "target", process variable "current" and the gains p, i, and d. Equivalent to: p * (target - current) + i * sum(target - current) - d * rate(current)

With all of these at your disposal, I'm excited to see what kind of contraptions you guys come up with, and I'm also open to some suggestions as to some things that could be added.

-WNP78, your funk master.

  • Log in to leave a comment
  • Profile image

    How do I show the AOA on screen

    4 days ago
  • Profile image
    88.2k Kerbango

    Is there an Funky trees input that we can use to turn on an indicator (light input or label) when an enemy locks on?

    11 days ago
  • Profile image

    this crap can fry my brain in under a second just by looking at a funky tree plane

    12 days ago
  • Profile image

    @Speedhunter i just had to figure out how to get the mod function. never needed it before in my 7.5 years of playing this game. what a coincidence :0

    turns out the repeat() function does exactly that ^^

    +1 27 days ago
  • Profile image

    How much of this functionality and syntax for inputs is also usable from a funk block? Ideally it would be the same across both as made sense

    +1 one month ago
  • Profile image

    @WNP78
    Actually, it might be easier just to show you what I mean on an unlisted post, if that's alright with you.

    one month ago
  • Profile image

    @WNP78
    Thanks!
    Another question,
    I have:
    {GunRateButton != AcmCover?"<alpha=#FF><color=#FF0000>HI":"<alpha=#20><color=#000000>HI"}
    {GunRateButton != AcmCover?"<alpha=#20><color=#000000>LOW":"<alpha=#FF><color=#FF0000>LOW"}
    How can I make it so if AcmCover is turned on then GunRateButton is turned on, when AcmCover is turned off it still displays LOW?
    Sorry if this is difficult to understand, I didn’t explain it very well.
    ALSO, would you mind how I could use the same
    {value ? "" : ""}
    format with which weapon is selected… if you don’t mind? :)

    one month ago
  • Profile image
    Dev WNP78

    @LoneSpaceGaming with boolean values, != is logically equivalent to XOR

    one month ago
  • Profile image

    @AristocraticFeelings
    It should be:
    {(TAS < 270) & (AltitudeAgl > 0) ? "<alpha=#80>STALL" : ""}
    Make sure you are using "" and not “”
    I’ll go check that this works.

    Edit: It works. And if I were you I would personally use AoA instead of airspeed, but you do you. Also, I would suggest lowering the stall speed WAY down.

    one month ago
  • Profile image

    Is there anyway to have XOR?

    one month ago
  • Profile image

    @EJBoss97
    I don’t think you can change inputs on things like that.

    +1 one month ago
  • Profile image
    419 EJBoss97

    is there a way to use variables to make a countermeasure pod fire off when the machine gun input is pressed?

    one month ago
  • Profile image
    32.6k Speedhunter

    @WNP78 is there a modulus operator? (akin to % in other programming languages)

    Where I can say ((ammo(name)%2) == 1) ? FireWeapons : 0

    Basically the input FireWeapons only works when the number of ammo is an odd number

    one month ago
  • Profile image
    Dev WNP78

    @darthgently in SP there is a menu you can open that allows you to create custom craft-level variables. You can enter the name of the variable, followed by a value it will be set to every frame. If you press the button to expand the full properties, you can also set an assignment priority that can change how it will act if the same variable is written to from multiple places, and also a condition which the variable will only update if said condition is true. In order to "set" a variable when something occurs, you can just make a setter with the condition set to only run that line when the condition is true.

    one month ago
  • Profile image

    I was reading that wrong. That clarifies. But what is this "variables system" you refer to? Variables can be assigned within funk? As in not just assigning the result of funk in a set variable block?

    one month ago
  • Profile image
    Dev WNP78

    @darthgently yeah, you can't really do it with PID directly. In the post it shows how you can deconstruct PID into sum and rate, so you'd use that NewSum in its place

    +1 one month ago
  • Profile image

    @WNP78 From description of PID() it appears to rely on sum() for the integral so I was hoping to use PID() with some not yet documented way to reset sum(). I'll roll my own in funk and consider the solutions you describe, they all look promising. The last one does seem to leave sum() with its accumulated value though if I'm understanding how it works

    one month ago
  • Profile image
    Dev WNP78

    @darthgently There are a few ways you could achieve that kind of behaviour.

    One is to use the smooth function, which would have a conditional expression in both arguments. In normal mode the target point would be something like sign(x) * a_big_number where x is the input that would have gone to sum, so that the smooth is always moving towards that very far away target in the direction you want it to go, and the max movement speed is abs(x), so the speed the input changes. When in reset mode, the target value would be zero, and the speed would be set to a really high number so it can reach zero in a single frame.

    The second way would be to use the variables system to keep a zero value used to "calibrate" the sum, kind of like how a digital scales calibrates. It would look something like
    RawSum : sum(x)
    SumZero : RawSum with the condition set to only run this line when you want to reset it
    NewSum: RawSum - SumZero

    +1 one month ago
  • Profile image

    Is there a way to reset sum() to alleviate windup in PID()?

    one month ago
  • Profile image

    @AristocraticFeelings
    Yes, why is the stall at 972 kmph😭??
    The tas unit used in these functions is in metres per second,not kmph
    So simply:
    {(TAS*3.6)<270 ? {(AltitudeAgl)>0 ? "<alpha#80>STALL" : "" : "" }

    +1 one month ago
  • Profile image

    @Voidchaser
    smooth(clamp01(Landing gear),1/3)

    After the comma, 1/how much delay you want in seconds ,here I gave it 3 second delay.
    If u have further questions,mention me .

    one month ago
  • Profile image
    0 Minn

    @Yish42 i mean how to make speed limit on engine or wheel some vehicle are very fast

    one month ago
  • Profile image

    {(TAS)<270 ? {(AltitudeAgl)>0 ? "<alpha#80>STALL" : "" : "" } Can someone help to this goddamn stupid funky tree code

    2 months ago
  • Profile image

    How do I make a landing gear hinge rotator have a delay

    +2 2 months ago
  • Profile image
    6,324 Zuznik8

    Are you going to add some kind of variable which tells you whether the enemy has locked you or not?

    2 months ago
  • Log in to see more comments