# Section 3: State Machine

## Section Intro - State Machine

There are no notes for this lecture.

## What is a State machine?

In this lecture, we discussed what a state machine is and why it's useful. We defined two terms.

* **State** - Refers to the current action being performed by the player, such as walking, attacking or dashing.
* **State Machine** - Refers to a program responsible for switching between states and managing them.

## Creating an Idle and Move State

In this lecture, we created classes to represent each state for the player. One class per state. For the idle state, we wrote the following code:

```csharp
using Godot;
using System;

public partial class PlayerIdleState : Node
{
    public override void _Ready()
    {
        Player characterNode = GetOwner<Player>();
        characterNode.animPlayerNode.Play(GameConstants.ANIM_IDLE);
    }
}
```

When the state is initialized, we're grabbing the `Player` class since this class is attached to the root node. The root node is considered to be the owner of all the other nodes in the hierarchy for a scene. Once we grab the `Player` class, we're accessing the `AnimationPlayer` node to play the idle animation.

We had to update our references to the `AnimationPlayer` node by changing their access modifiers to `public` instead of `private`.

```csharp
[Export] public AnimationPlayer animPlayerNode;
[Export] public Sprite3D spriteNode;
```

## Building the State Machine

In this lecture, we worked on a custom state machine to select an initial state and disable all other states. First, we created a node with an attached script that looks something like this:

```csharp
using Godot;
using System;

public partial class StateMachine : Node
{
    [Export] private Node currentState;
    [Export] private Node[] states;

    public override void _Ready()
    {
        foreach (var state in states)
        {
            state.Notification(5001);
        }

        currentState.Notification(5002);
    }
}
```

In the above example, we're doing the following:

1. Exporting a field for storing the current state, which will be a node.
2. Exporting another field for storing an array of valid states.
3. In the `_Ready` method, we're sending a notification to each node that it should be disabled.
4. Lastly, we're enabling the current state with a notification as well.

{% hint style="info" %}
Godot uses the notification system itself, so make sure that you're using a number that isn't taken by Godot. You can always refer to the documentation for a list of officially taken notification numbers.
{% endhint %}

After sending a notification, nodes can receive a notification by overriding the `_Notification` method like we did in the `PlayerIdleState` class.

```csharp
public override void _Notification(int what)
{
    base._Notification(what);

    if (what == 5001)
    {
        GD.Print("Exiting Idle state");
    }
    else if (what == 5002)
    {
        Player characterNode = GetOwner<Player>();
        characterNode.animPlayerNode.Play(GameConstants.ANIM_IDLE);
    }
}
```

In this example, we're calling the base `_Notification` method as we don't want to completely override Godot's default behavior for handling notifications. If Godot doesn't have a response to a specific notification, we handled it ourselves. The number `5001` means we should disable a node. The number `5002` means we should enable a node. When enabling a node, we're just playing the state's animation.

### Resources

* Notifications - <https://docs.godotengine.org/en/stable/tutorials/best_practices/godot_notifications.html>&#x20;
* Node Constants - <https://docs.godotengine.org/en/stable/classes/class_node.html#constants>

## Transitioning States

In this lecture, we updated our state machine to allow states to perform transitions. In the **StateMachine.cs** file,  we defined  a `SwitchState` method that has a generic called `T` to help it search for a state to switch to.&#x20;

```csharp
public void SwitchState<T>()
{
    Node newState = null;

    foreach (Node state in states)
    {
        if (state is T)
        {
            newState = state;
        }
    }

    if (newState == null) { return; }

    currentState = newState;
    currentState.Notification(5001);
}
```

During this method, we're doing a few things.

1. Looping through the states stored in the `states` field.&#x20;
2. On each iteration, we're checking if the current item in the iteration has the `T` class. If it does, we're updating the `newState` variable to this state.
3. After the loop, we're checking if a state was found. If it wasn't, we're stopping the rest of method from running.
4. Otherwise, we're updating the `currentState` variable with the `newState` variable and then sending a notification to enable the state.

To transition between states, we can call this method with the state we'd like to switch to. For example, in the `PlayerIdleState` class, we're switching to the `PlayerMoveState` if the player's direction is not a vector zero.

```csharp
public override void _PhysicsProcess(double delta)
{
    if (characterNode.direction != Vector2.Zero)
    {
        characterNode.stateMachineNode.SwitchState<PlayerMoveState>();
    }
}
```

## Disabling Nodes

In this lecture, we disabled nodes by calling the `SetPhysicsProcess` method from the `Node` class. This method instructs Godot whether it should bother calling the `_PhysicsProcess` method on every frame. It accepts a boolean value. For example, in our `_Ready` method for both states, we're passing in `false` to disable this behavior.

```csharp
public override void _Ready()
{
    characterNode = GetOwner<Player>();
    SetPhysicsProcess(false);
}
```

To enable the physics process, we're sending out a new notification from the `SwitchState` method.

```csharp
currentState.Notification(5002);
currentState = newState;
currentState.Notification(5001);
```

We're using `5002` as the notification number for when a node should be disabled. It's important that we disable the current state before switching to a new one.&#x20;

Lastly, in either states, we're just checking for the notification number to determine whether the state should be enabled or disabled.

```csharp
if (what == 5001)
{
    SetPhysicsProcess(true);
    characterNode.animPlayerNode.Play(GameConstants.ANIM_IDLE);
}
else if (what == 5002)
{
    SetPhysicsProcess(false);
}
```

## Setting up the Dash State

In this lecture, we took the time to set up a dash state by adding a dash animation, adding a DashState node, and then playing the animation. The only thing we did unique in this lecture was added the state nodes as child nodes to the **StateMachine** node so that the nodes are ready before the state machine is ready. This way, we have any references that we need before entering or exiting a state.

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

## Transitioning to the Dash State

In this lecture, we transitioned to the dash state from the idle and move state. To perform this task, we had to query the `Input` class for the action pressed from the `_Input` method in both states like so:

```csharp
if (Input.IsActionJustPressed(GameConstants.INPUT_DASH))
{
    characterNode.stateMachineNode.SwitchState<PlayerDashState>();
}
```

Godot provides two methods from the `Input` class to check if an action was pressed.

* `IsActionPressed` - Can be used whenever you need to check if a button is currently pressed.
* `IsActionJustPressed` -  Can be used whenever you need to check if an action was just pressed. Doesn't bother checking if a button is continuously being held down.

In this case, we're using the `IsActionJustPressed` since we're not interesting in checking if the action is continuously being pressed.

Lastly, we called a method called `SetProcessInput` to disable/enable any state that has the `_Input` method. Passing in `false` prevents this method from being called. Here's an example.

```csharp
SetProcessInput(false);
```

## Adding a Dash Timer

In this lecture, we added a Timer node. During this process, we had to subscribe to a signal from the Timer node. Signals are a feature for storing and emitting events. The Timer node has an event for when the timer runs out called `timeout`. If you're using C#, the signal is pascal cased, so the name is `Timeout`.&#x20;

```csharp
dashTimerNode.Timeout += HandleDashTimeout;
```

To subscribe to a signal, we must use the `+=` operator. The value for a signal is the name of a method that you want to run when the event is emitted. In this example, we're setting the method to `HandleDashTimeout`.  The method we wrote looks like this where we're switching to the idle state.

```csharp
private void HandleDashTimeout()
{
    characterNode.stateMachineNode.SwitchState<PlayerIdleState>();
}
```

Lastly, we started the timer by calling the `Start` method on the variable holding a reference to the timer.

```csharp
dashTimerNode.Start();
```

### Resources

* Timer Class - <https://docs.godotengine.org/en/stable/classes/class_timer.html>

## Finalizing the Dash State

In this lecture, we finalized the state by moving the player while they're in the dash state. During this process, we had to check if the player was transitioning from the idle state.

```csharp
if (characterNode.Velocity == Vector3.Zero)
{
    characterNode.Velocity = characterNode.spriteNode.FlipH ?
        Vector3.Left :
        Vector3.Right;
}
```

By checking if the `Velocity` property is a vector zero, we can check to make sure the player is moving. If they aren't, we're setting the `Velocity` property to either the `Vector3.Left` or `Vector3.Right` property.&#x20;

In this example, we're using a ternary operator. A ternary operator has the condition to the left of the `?` character. If the condition evaluates to `true`, the value to the right of the same character is used. Otherwise, the value to the right of the `:` character is used.&#x20;

## Reusing States With Inheritance

In this lecture, we outsourced some of the logic for a state in a separate class. This class is called `PlayerState` and it looks like the following:

```csharp
using Godot;

public partial class PlayerState : Node
{
    protected Player characterNode;

    public override void _Ready()
    {
        characterNode = GetOwner<Player>();
        SetPhysicsProcess(false);
        SetProcessInput(false);
    }

    public override void _Notification(int what)
    {
        base._Notification(what);

        if (what == 5001)
        {
            SetPhysicsProcess(true);
            SetProcessInput(true);
            EnterState();
        }
        else if (what == 5002)
        {
            SetPhysicsProcess(false);
            SetProcessInput(false);
        }
    }

    protected virtual void EnterState() { }

}
```

In this example, we're doing a few things.

1. We're inheriting from the `Node` class since only one class can be inherited and all states will need access to the node.
2. The `characterNode` field is set to `protected` so that child classes have access to the field.
3. We're defining a method called `EnterState()`, which can be overriden since it's `virtual`. In addition, it's called after the `SetProcessInput(true)` method when we're entering the state. This way, child classes will be able to perform additional setup if they need to.

After defining this class, we inherited it from all of our states. As an example, we did the following for the idle state:

```csharp
public partial class PlayerIdleState : PlayerState
{
    protected override void EnterState()
    {
        characterNode.AnimPlayerNode.Play(GameConstants.ANIM_IDLE);
    }
}
```

In this example, we're inheriting from the `PlayerState` class and overriding the `EnterState()` method so that we can play the idle animation.&#x20;

In the `PlayerDashState` class, we also had to override the `_Ready()` method even though this method was defined in the `PlayerState` class. In that case, we can use the `base` keyword to access the original `_Ready()` method so that we can use the parent and child methods.&#x20;

```csharp
public override void _Ready()
{
    base._Ready();

    dashTimerNode.Timeout += HandleDashTimeout;
}
```

## Using Abstract Classes

In this lecture, we added the `abstract` class to the `PlayerState` class. By adding this keyword, the class cannot be instantiated. This prevents us from accidentally applying this class to a node in Godot as our game won't work when trying to attach a `abstract` class.

```csharp
public abstract partial class PlayerState : Node
{

}
```

## Dealing with Magic Numbers

In this lecture, we talked about magic numbers. A magic number is a number that holds meaning and is not just some ordinary number. Magic numbers can cause confusion because their meaning will not be universally understood from developer to developer. Whenever you have a magic number, it's considered good practice to define a variable for storing the magic number to provide a description.&#x20;

We had two magic numbers in our codebase, which were 5001 and 5002. So, we decided to add these as constants to the `GameConstants` class.

```csharp
public class GameConstants
{
    // Notifications
    public const int NOTIFICATION_ENTER_STATE = 5001;
    public const int NOTIFICATION_EXIT_STATE = 5002;
}
```

We then used these constants like so:

```csharp
currentState.Notification(GameConstants.NOTIFICATION_ENTER_STATE);
```

## Export Property Hints

In this lecture, we learned how to customize a field by adding controls for modifying a value. For example, we can add a slider to a field for numeric fields by adding the `PropertyHint.Range` to an exported variable. In the `PlayerDashState` class, we modifed the `speed` field like so:

```csharp
[Export(PropertyHint.Range, "0,20,0.1")] private float speed = 10f;
```

We updated the `Export` variable by passing in two values. First, we must provide the type of property that is being modified. By setting it to `PropertyHint.Range`, Godot will understand that we have a number and will add a slider.&#x20;

The second argument to this attribute are settings. For range sliders, we're setting a minimum threshold, maximum threshold, and the value to increment the number when moving the slider.

### Resources

* C# Exported Properties - <https://docs.godotengine.org/en/stable/tutorials/scripting/c_sharp/c_sharp_exports.html>

## Auto Properties

In this lecture, we talked about how auto-properties can be helpful in C#. So far, we've been using `public` for fields that should be accessible outside of an existing class. However, that also allows them to be modified outside the class. To prevent a field from being modified but still allow it to be read, we can change it to a property.

A property allows us to refine how a variable is exposed. Here's an example with the `AnimPlayerNode.`

```csharp
[Export] public AnimationPlayer AnimPlayerNode { get; private set; }
```

By adding the `get` and `set` keywords, we can change the access modifiers for each of them. For example, the `set` has the `private` modifier. This means that external classes will not be able to change the field. The property can only be read from other classes.

In addition, we changed the name to pascal case since it's a common naming convention for properties to be pascal cased.&#x20;


---

# 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://luisramirez.gitbook.io/godot-2.5d-rpg-course/section-3-state-machine.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.
