# Material proxies programming

Material proxies can perform specific tasks in a VMT. Even though the scripting is rudimentary, it stills allows to write basic programs. This page aims to show how to create basic logical connectors for VMTs using material proxies. The huge advantage of material proxies over VScripts is that they are allowed to run on most official Valve servers.

Any number of proxies can be added to a material; they will be executed in the order in which they appear.

## If (x > y) {a = b} else {a = c}

The `LessOrEqual` allows to write a basic if (x > y) { a = b } else { a = c } condition. Removing the `else` is done by setting the same variable as `resultVar` and `LessEqualVar`.

The block of code below stores 1 (\$a) into \$c if the player speed (\$x) is higher than 0 (\$y), otherwise it stores 2 (\$b) into \$c.

```VertexLitGeneric
{
\$x "0"
\$y "0"
\$a "1"
\$b "2"
\$c "0"

Proxies
{

PlayerSpeed
{
scale		        "1"
resultVar 		"\$x"
}

LessOrEqual
{
srcVar1 		        "\$x"   // if \$x
srcVar2 		        "\$y"   // > \$y
resultVar 		"\$a"   // { \$a =
greaterVar 	        "\$b"   // \$b }
LessEqualVar 	        "\$c"   // else { \$a = \$c }
}

}
}
```

## If (x == y) {a = b} else {a = c}

It is possible to write an EQUALS operator with the use of three material proxies.

The block of code below stores 1 (\$a) into \$c if the player speed (\$x) is exactly 300 (\$y), otherwise it stores 2 (\$b) into \$c.

What it technically does is that is checks if there's a difference of 0 between \$x and \$y. Mathematically speaking, if the absolute value or the subtraction between two numbers is equal to 0, it means that the two numbers that were subtracted were the same.

```VertexLitGeneric
{
\$x "0"
\$y "300"
\$a "1"
\$b "2"
\$c "0"

\$zero "0"
\$xsubtract "0"

Proxies
{

PlayerSpeed
{
scale		        "1"
resultVar 		"\$x"
}

Subtract
{
srcVar1		        "\$x"
srcVar2 		        "\$y"
resultVar 		"\$xsubtract"
}

Abs
{
srcVar1		        "\$xsubtract"
resultVar 		"\$xsubtract"
}

LessOrEqual
{
srcVar1 		        "\$xsubtract" // if \$x
srcVar2 		        "\$zero" // == \$y (has a difference of 0 with \$y)
resultVar 		"\$a"   // { \$a =
greaterVar 	        "\$b"   // \$b }
LessEqualVar 	        "\$c"   // else { \$a = \$c }
}

}
}
```

## if (\$x > \$y AND \$j <= \$k) {\$a = \$b} else {\$a = \$c}

It is possible to create AND operators using material proxies by multiplying 2 conditions together. For each condition : 0 = the condition is not met / 1 = the condition is met. Multiplying anything by 0 returns 0, therefore, if any of the two conditions is not met, the multiplication will always be equal to 0. It's only when each factor of the multiplication is over 0 that its result will be over 0.

The following code sets \$frame to 1 if the player speed is over 200 AND that a random number associated with the entity is less or equal to 10, otherwise it sets \$frame to 0.

```VertexLitGeneric
{

\$speed            "0"
\$random           "0"

\$zero             "0"
\$one              "1"
\$ten              "10"
\$th               "200"

\$speedcondition   "0"   // 0 = condition is not met / 1 = condition is met
\$randomconditon   "0"   // ''
\$bothconditions   "0"   // ''

Proxies
{

PlayerSpeed
{
scale		        "1"
resultVar 		"\$speed"
}

LessOrEqual
{
srcVar1 		        "\$speed"             // if \$speed
srcVar2 		        "\$th"                // > 200
resultVar 		"\$speedcondition"    // { \$speedcondition
greaterVar 	        "\$one"               // = 1 }
LessEqualVar 	        "\$zero"              // else { \$speedcondition = 0 }
}

EntityRandom
{
scale		        "100"
resultVar 		"\$random"
}

LessOrEqual
{
srcVar1 		        "\$random"             // if \$random
srcVar2 		        "\$ten"                // > 10
resultVar 		"\$randomconditon"     // { \$randomconditon
greaterVar 	        "\$zero"               // = 0 }
LessEqualVar 	        "\$one"                // else { \$randomconditon = 1 }
}

Multiply                                                // if (\$speedcondition AND \$randomconditon) > 0  {\$bothconditions > 0} else {\$bothconditions = 0}
{
srcVar1 		        "\$speedcondition"
srcVar2 		        "\$randomconditon"
resultVar 		"\$bothconditions"
}

LessOrEqual
{
srcVar1 		        "\$bothconditions"      // if \$bothconditions
srcVar2 		        "\$zero"                // > 0
resultVar 		"\$frame"               // { \$frame
greaterVar 	        "\$one"                 // = 1 }
LessEqualVar 	        "\$zero"                // else { \$frame = 0 }
}

}
}
```

## if (\$x > \$y OR \$j > \$k) {a = b} else {a = c}

It is possible to create OR operators using material proxies. It can be done by adding 2 conditions together. For each condition : 0 = the condition is not met / 1 = the condition is met. Adding the two conditions will provide a result higher than 0 if any of the two conditions is met, resulting in an "OR" operator.

The following code sets \$frame to 1 if the player speed is over 200 OR if the player is looking almost at the center of the material (\$view > 80), otherwise it sets \$frame to 0.

```VertexLitGeneric
{

\$speed            "0"
\$view             "0"

\$zero             "0"
\$one              "1"
\$eighty           "80"
\$th               "200"

\$speedcondition   "0"   // 0 = condition is not met / 1 = condition is met
\$randomconditon   "0"   // ''
\$anycondition     "0"   // ''

Proxies
{

PlayerSpeed
{
scale		        "1"
resultVar 		"\$speed"
}

LessOrEqual
{
srcVar1 		        "\$speed"             // if \$speed
srcVar2 		        "\$th"                // > 200
resultVar 		"\$speedcondition"    // { \$speedcondition
greaterVar 	        "\$one"               // = 1 }
LessEqualVar 	        "\$zero"              // else { \$speedcondition = 0 }
}

PlayerView
{
scale		        "100"
resultVar 		"\$view"
}

LessOrEqual
{
srcVar1 		        "\$view"               // if \$view
srcVar2 		        "\$eighty"             // > 80
resultVar 		"\$viewconditon"       // { \$viewconditon
greaterVar 	        "\$zero"               // = 1 }
LessEqualVar 	        "\$one"                // else { \$viewconditon = 0 }
}

Add                                                   // if (\$speedcondition OR \$viewconditon) > 0  {\$bothconditions > 0} else {\$bothconditions = 0}
{
srcVar1 		        "\$speedcondition"
srcVar2 		        "\$viewonditon"
resultVar 		"\$anycondition"
}

LessOrEqual
{
srcVar1 		        "\$anycondition"        // if \$anycondition
srcVar2 		        "\$zero"                // > 0
resultVar 		"\$frame"               // { \$frame
greaterVar 	        "\$one"                 // = 1 }
LessEqualVar 	        "\$zero"                // else { \$frame = 0 }
}

}
}
```

## WHILE LinearRamp

A WHILE `LinearRamp` is a complex material proxy construction that allows a `LinearRamp` to increment as long as a condition as met. The `LinearRamp` virtually resets it to 0 as soon as the condition is no more met.

It is done by subtracting the result of the `LinearRamp` proxy from itself if the condition is not met, and otherwise subtracting the value the `LinearRamp` material proxy had when the condition was not met for the last time from its current value.

The following code increments the \$rampresult value by 1 every second as long as the player is static (\$speed <= 0), otherwise, it resets it to 0.

```VertexLitGeneric
{

\$speed           "0"

\$zero            "0"

\$ramp            "0"
\$rampcorr        "0"
\$rampresult      "0"

Proxies
{

PlayerSpeed
{
scale		        "1"
resultVar 		"\$speed"
}

LinearRamp					// Generates a Linear Ramp that increments its value by 1 every [rate] second
{
rate 		        "1"
resultVar 		"\$ramp"
}

LessOrEqual					 // This will result in storing a correction that is equal to the \$ramp value if the condition is not met
{
srcVar1 		"\$playerspeed"   // if \$playerspeed
srcVar2 		"\$zero"          // > 0
resultVar 		"\$rampcorr"      // \$rampcorr =
LessEqualVar 	        "\$ramp"          // \$ramp (triggers the ramp reset)
greaterVar 	        "\$rampcorr"      // else { \$rampcorr = \$rampcorr }
}

Subtract					// If the correction is equal to \$ramp, the LinearRamp (stored in \$rampresult) will virtually return to 0.
{
srcVar1		        "\$ramp"
srcVar2 		"\$rampcorr"
resultVar 		"\$rampresult"   // Final result of the LinearRamp that can be used further in the code as a timer or as a condition
}

}
}
```

It is also possible to modify the `LessOrEqual` material proxy to create a LinearRamp that loops at a certain value (\$valuetoloopat) :

```	        LessOrEqual
{
srcVar1 		"\$rampresult"       // if \$rampresult
srcVar2 		"\$valuetoloopat"    // > \$valuetoloopat (to define in the variables block)
resultVar 		"\$rampcorr"         // \$rampcorr =
LessEqualVar 	        "\$ramp"             // \$ramp
greaterVar 	        "\$rampcorr"         // else { }
}
```