Stingray.StateMachine.Godot 1.0.5

dotnet add package Stingray.StateMachine.Godot --version 1.0.5
                    
NuGet\Install-Package Stingray.StateMachine.Godot -Version 1.0.5
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Stingray.StateMachine.Godot" Version="1.0.5" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Stingray.StateMachine.Godot" Version="1.0.5" />
                    
Directory.Packages.props
<PackageReference Include="Stingray.StateMachine.Godot" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Stingray.StateMachine.Godot --version 1.0.5
                    
#r "nuget: Stingray.StateMachine.Godot, 1.0.5"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Stingray.StateMachine.Godot@1.0.5
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Stingray.StateMachine.Godot&version=1.0.5
                    
Install as a Cake Addin
#tool nuget:?package=Stingray.StateMachine.Godot&version=1.0.5
                    
Install as a Cake Tool

Stingray.StateMachine

A lightweight, framework-agnostic hierarchical state machine library for .NET 8.0+.

Features

  • 🎯 Type-Safe: Uses C# types for state identification and transitions.
  • Generic: Context-aware (IState<TContext>) for easy state sharing.
  • 🎣 Event-Driven: Hooks for StateEntered, StateExited, StateTransitioned, and Completed.
  • 🎮 Godot-Friendly: Optional TransitionToScene that loads scenes by type name.

Installation

Add the generic NuGet package to your project (ensure you have built/packed the solution):

dotnet add package Stingray.StateMachine

Usage

1. Define Your Context

The context is the shared data explicitly passed to your states. It must implement IContext.

using Stingray.StateMachine;

public class GameContext : IContext {
    public int PlayerId { get; set; }
    public bool IsGameOver { get; set; }
}

2. Define States

Implement IState<TContext>. Each method receives both the context and the state machine instance. When used with Godot, your state classes should be Nodes (scenes) so the current scene can be cast to IState<TContext>.

using Stingray.StateMachine;

public class IdleState : IState<GameContext> {
    public void Enter(GameContext context, StateMachine<GameContext> stateMachine) {
        Console.WriteLine("Entering Idle");
    }

    public StateResult<GameContext> Execute(GameContext context, StateMachine<GameContext> stateMachine) {
        if (context.IsGameOver) {
            return StateResult<GameContext>.Complete();
        }

        // Transition to another state by type
        return StateResult<GameContext>.TransitionTo<PlayState>();
    }

    public void Exit(GameContext context, StateMachine<GameContext> stateMachine) {
        Console.WriteLine("Exiting Idle");
    }
}

public class PlayState : IState<GameContext> { ... }

3. Setup and Run

var context = new GameContext();
var fsm = new StateMachine<GameContext>();

// Build the scene index once at startup (Godot only).
// A good place is an Autoload singleton or the main scene's _Ready().
ScenePathIndex.Build();

// Register states
fsm.AddState<IdleState>()
   .AddState<PlayState>();

// Set entry point
fsm.SetInitialState<IdleState>();

// Start
fsm.Start(context);

// Update loop (e.g., in your game loop)
while (fsm.IsRunning) {
    fsm.Step(context);
}

Godot Example (TransitionToScene)

public partial class IdleState : Node, IState<GameContext> {
    public void Enter(GameContext context, StateMachine<GameContext> stateMachine) {
        // ...
    }

    public StateResult<GameContext> Execute(GameContext context, StateMachine<GameContext> stateMachine) {
        return StateResult<GameContext>.TransitionTo<PlayState>();
    }

    public void Exit(GameContext context, StateMachine<GameContext> stateMachine) {
        // ...
    }
}

public partial class PlayState : Node, IState<GameContext> {
    public void Enter(GameContext context, StateMachine<GameContext> stateMachine) { }
    public StateResult<GameContext> Execute(GameContext context, StateMachine<GameContext> stateMachine) {
        // Load a new scene by type name
        stateMachine.TransitionToScene<RewardSelectionScene>(context);
        return StateResult<GameContext>.Continue();
    }
    public void Exit(GameContext context, StateMachine<GameContext> stateMachine) { }
}

Godot Scene Convention

TransitionToScene resolves scene files by class name. The .tscn file name must match the state class name:

  • RewardSelectionSceneres://Any/Folder/RewardSelectionScene.tscn

Scene names must be unique across the project. The index will throw a clear error on duplicates.

Godot Notes

  • ScenePathIndex.Build() throws if two .tscn files share the same name.
  • If a matching scene file is not found, TransitionToScene throws and tells you the expected file name.

API Reference

StateMachine<TContext>

  • AddState(IState<T> state): Registers a state type from an instance (instance is not stored).
  • AddState(Type stateType): Registers a state by type.
  • AddState<TState>(): Registers a state by type with compile-time checking.
  • SetInitialState<TState>(): Sets the starting state.
  • Start(TContext context): Enters the initial state.
  • Step(TContext context): Executes the current state's logic. Returns true if completed.
  • TransitionTo<TState>(TContext context): Forcefully transitions to a state.
  • TransitionToScene<TState>(TContext context): Transitions to a state and attempts to change a Godot scene using ScenePathIndex.
  • SceneEnterRetryLimit: Number of frames to retry waiting for CurrentScene after TransitionToScene. Default is 60 (retries continue even if the limit is exceeded).

ScenePathIndex

  • Build(): Scans res:// for .tscn files using Godot's APIs and builds a name-to-path index.

StateResult<TContext>

  • Continue(): Stay in current state.
  • TransitionTo<TState>(): Switch to a new state.
  • TransitionToScene<TState>(): Switch to a new state and load a Godot scene.
  • Complete(): End the state machine execution.

License

MIT

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net8.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.5 96 9/6/2026
1.0.4 90 9/6/2026

- Added TransitionToScene to allow for transitions to scenes and update