# Functions

As mentioned in the chapter [Functions](/2.5/getting-started/writing-in-yarn/functions.md), Yarn can access user-defined functions. A collection of functions is called a *library* and can be accessed through a `DialogueRunner`.

## Function Registration

For an easy example, let's modify the code used in the [Quick Start](/2.5/using-yarnspinner-with-rust/quick-start.md) to provide a simple `pow` function to Yarn:

```rust
fn spawn_dialogue_runner(mut commands: Commands, project: Res<YarnProject>) {
    let mut dialogue_runner = project.create_dialogue_runner();
    // Add our custom function to the dialogue runner
    dialogue_runner.library_mut().add_function("pow", pow);
    dialogue_runner.start_node("Start");
    commands.spawn(dialogue_runner);
}

fn pow(base: f32, exponent: f32) -> f32 {
    base.powf(exponent)
}
```

The following snippet is of special importance:

```rust
dialogue_runner.library_mut().add_function("pow", pow);
```

The first parameter of `add_function()` is the name of the function as seen by Yarn, `"pow"` in this case. The second parameter is the Rust function that will be called in the background. Here, we reference the function definition of `fn pow(...)`, but you could also register a lambda.

This `pow` function can now be called from the Yarn file like this:

```
title: Start
---
Two to the power of three is {pow(2,3)}
===
```

Which will result in the following output:

<figure><img src="/files/ZAe9dx22LCiNoU0oDSsP" alt=""><figcaption></figcaption></figure>

## Allowed Signatures

Custom functions need to follow some rules. Don't worry, they're pretty lax.

* Their parameter and output types need to be primitive types or `String`
* Parameters are allowed to be references
* Parameters can have the special type `YarnValue`, which stands for any input type. Additionally, functions are assumed to have no side effects. You can read the full list of requirements in the docs for `YarnFn`.

Here are some examples of valid functions:

```rust
fn add(a: f32, b: f32) -> f32 {
    a + b
}

fn concat(a: &str, b: &str) -> String {
    format!("{a}{b}")
}

fn greet(name: &str, age: usize) -> String {
    format!("Hello {name}, you are {age} years old!")
}

fn format_anything(value: YarnValue) -> String {
    format!("Got the following value: {value}")
}
```

If you need functions that have side effects, e.g. for manipulating the game world, use [custom commands](/2.5/using-yarnspinner-with-rust/creating-commands-functions/creating-commands.md) instead.

## Size constraints

Registered Rust functions can have a maximum of 16 parameters. If you need more, you can wrap parameters in tuples:

```rust
fn add((a, b): (f32, f32)) -> f32 {
    a + b
}
```

Tuples are treated as separate parameters when calling the function from Yarn:

```
title: Start
---
Two plus three is {add(2, 3)}
===
```

Since tuples can be nested, you can use have potentially infinite parameters.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.yarnspinner.dev/2.5/using-yarnspinner-with-rust/creating-commands-functions/creating-functions.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
