npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@rbxts/roblox-state-machine

v1.0.1

Published

A simple finite state machine implementation for RobloxTS

Readme

RobloxStateMachine

A simple finite state machine library very much inspired by prooheckcp's RobloxStateMachine.

Was mainly done because I wanted to port RobloxStateMachine to RobloxTS.

StateMachine

constructor(InitialState, States, MustCallHeartbeatManually, Data)

Parameters

  • InitialState - The initial state that the state machine will enter. Accepts the state name or constructor.
  • States - An array of states that the state machine will be able to access and switch to.
  • MustCallHeartbeatManually - If true, the OnHeartbeat method in every state will have to be called manually with the StateMachine.ExecuteHeartbeatEvent method.
  • Data - Can be anything you wish. This data will be visible by all states and transitions. Usually an object.
import { StateMachine, State, StateConstructor } from "@rbxts/finite-state-machine";

function RequireStates(Path: Folder) {
    return Path.GetChildren().map(Child => require(Child as ModuleScript) as StateConstructor);
}

const NPC = {
    Instance: Workspace.NPC,

    Health: 100,
}

const Machine = new StateMachine(
    "Roaming",
    RequireStates(ReplicatedStorage.States),
    false,
    NPC
);

ChangeState(State)

Used to change the state of the machine.

Parameters

  • State - Can be either a string, a constructor or one of the states you get by calling StateMachine.GetStates()

GetCurrentState()

Returns

  • State - The State that is currently on.

GetPreviousState()

Returns

  • State - The previous State that used to be on.

GetStates()

Returns

  • States - An array of states that the state machine has.

ExecuteHeartbeatEvent(Delta)

A method that when called, calls the OnHeartbeat method of both the current state and the current state's transitions.

Parameters

  • Delta - The delta time of the heartbeat event.

Destroy()

Stops the machine from running.

StateChanged

An event that fires whenever the state machine changes states

StateMachine.StateChanged.Connect((NewState, OldState) => {
    // ...
})

StateMachine.ExecuteHeartbeatEvents(Delta, OnlyManualStateMachines)

A Static method that can be called to execute the OnHeartbeat methods on ALL the active StateMachines. Useful for when you want to call the OnHeartbeat events at different times/with different DeltaTime or use some other event like RenderStepped.

Parameters

  • Delta - The delta time

  • OnlyManualStateMachines - If true, will call the OnHeartbeat events only on State Machines that have MustCallHeartbeatManually to true. Otherwise only the ones who have it to false.

Creating States

Let's say we have a state named Roaming.

import { State } from "@rbxts/roblox-state-machine";
import { NPCType } from "./Types";

// The Data parameter is the 4th parameter of the state machine constructor, and the type of data can be specified in the State<Data> type.
export = class Roaming extends State<NPCType> {
    // The transitions that this state will use. Is optional.
    // Documentation about transitions is further below.
    Transitions = []

    OnEnter(Data: NPCType) {
        // This is called when the state machine switches to this state.

        // Data can also be accessed with this.Data
    }

    OnLeave(Data: NPCType) {
        // Called when the state machine leaves this state
    }

    OnInit(Data: NPCType) {
        // Called when the state machine is constructed.
    }

    OnHeartbeat(Data: NPCType, Delta: number) {
        // Called every heartbeat or when StateMachine.ExecuteHeartbeatEvent is called while this state is currently on.

        if (Data.Anger > 100) this.ChangeState("Angry");
    }

    OnDestroy(Data: NPCType) {
        // Called when the state machine is destroyed.
    }

    // A method that is called everytime the state machine tries to change states. If it returns false, the state machine won't change the current state.
    CanChangeState(Target: State<NPCType>) {
        // In this scenario, if the machine wants to switch to the Running state while it's in the Roaming state (this state), don't allow it to switch.
        return Target.Name !== "Running"
    }
}

And now we can create a state machine that uses this state.

import { StateMachine } from "@rbxts/roblox-state-machine";
import Roaming from "somewhere";

const NPC = ...

const Machine = new StateMachine("Roaming", [Roaming], false, NPC);

Do note that the machine starts immediately after it's constructed.

Transitions

Transitions can help with transitioning states. They serve as a little bonus on top of states.

Again, let's say we have a file named RunningTransition.

import { Transition } from "@rbxts/roblox-state-machine";
import { NPCType } from "./Types";

export = class RunningTransition extends Transition<NPCType> {
    // The target state that the transition will make the state machine transition to. Can be either a string, a State from StateMachine.GetStates() or a state constructor. See the OnHeartbeat method here.
    TargetState = "Running";

    OnEnter(Data: NPCType) {
        // This is called when the state machine switches to the state that uses this transition.

        // Data can also be accessed with this.Data
    }

    OnLeave(Data: NPCType) {
        // Called when the state machine leaves the state that uses this transition.
    }

    OnInit(Data: NPCType) {
        // Called when the state machine is constructed.
    }

    OnHeartbeat(Data: NPCType, Delta: number): boolean {
        // Called every heartbeat or when StateMachine.ExecuteHeartbeatEvent is called while the state that uses this transition is currently on. If this method returns true, the state machine will switch to the TargetState

        // In this case, if the npc anger is over 100, we will transition to the running state (Because the TargetState is set to Running).
        return Data.Anger > 100
    }

    OnDestroy(Data: NPCType) {
        // Called when the state machine is destroyed.
    }
}

We can apply this transition to a state like so:

import RunningTransition from "somewhere";

// RunningTransition can be used for other states, too.
class Roaming extends State<NPCType> {
    Transitions = [RunningTransition]
}

Final notes

States and transitions can inherit from other states/transitions. States and Transitions have most of the methods that StateMachine has.