Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.Sign up
Scripts are the primary way of interacting with FreePIE. Using scripts, you can specify not only the 1-to-1 button mappings common of most input mappers, but also the more nuanced, game-to-game logic for interpreting more complex inputs such as motion controller gestures or voice commands.
FreePIE 0.4.211.0 and later bases its scripting engine on Python. Like in most programming languages, execution in Python occurs line by line from top to bottom - each statement, whether it be a function call, variable assignment, or control instruction, happens one after the other. Relatively unique to Python is its use of whitespace: rather than use the curly braces and semicolons common of other languages, each statement always ends with a new line, and to indicate a block (such as a function body or if statement body), the "head" statement of the block ends in a colon and the lines underneath are indented:
# Define "doSomething" for later execution def doSomething(): x = 1 y = 2 # Define "giveMeSomething" for later execution def giveMeSomething(): return 0 x = giveMeSomething() if x == 2: doSomething() elif x == 1: diagnostics.debug("doSomething already ran!") else: x = 2
As shown above, comments are indicated with a
# character, as in Bash scripts or Batch files.
However, unlike normal Python execution and most other programming languages, FreePIE uses a continuous execution model. In other words, rather than running your script once, FreePIE will run your script over and over again until you explicitly stop it. This means that scripts can simply copy data they receive from FreePIE's inputs (such as the keyboard or mouse) and expect to receive the same data every time - it is unnecessary to write
while True: loops or other continuous polling constructs. For instance, the above script will first set x to 2, then to 1, and then will print
"doSomething already ran!" indefinitely.
In order to counteract some side effects of this, FreePIE also provides a few extra mechanisms to your scripts:
- Some devices do not update at every iteration (pretty much everything except keyboard and mouse). These devices instead provide
updateevent handlers to which you can add a function to be triggered when that device does update, so that you don't request information from the device that will be the same as it was the last time you checked:
def update(): #Do stuff if starting: freeTrack.update += update
- Some actions are only appropriate to take during the first iteration, such as subscribing to event handlers. Hence, FreePIE provides a global boolean variable called
Trueon the first iteration and
Falseotherwise (see above example).
- If you need to save data between iterations, use global variables. Python defines global variables using a special syntax that requires each function requesting the global variable to declare its use at the start of the function body. Initialize these variables to whatever they need to be within your
def update(): global yaw yaw = freeTrack.yaw if starting: yaw = 0 freeTrack.update += update
Other than these differences, FreePIE supports all Python 2 language constructs, including duck-typed variables, functions (including functions with mutable closures), classes/objects, enums (which the FreePIE libraries provide plenty of), etc. These features are well detailed in the Python syntax manual and are highlighted using syntax coloring in the FreePIE script editor.
FreePIE even includes the standard Python libs, importing them automatically so that you can use them in your script - even without using
yaw = math.degrees(freeTrack.yaw)
The code completion database does not currently support these libraries, though a future version of FreePIE will do so. In the meantime, feel free to consult the Python standard library reference for more details on how to use these libraries in your script. The
math library is especially helpful in FreePIE, containing plenty of useful functions for converting units and patterns from input devices into values more useful for simulating other inputs.
Please see the script examples for more ideas.