-
Notifications
You must be signed in to change notification settings - Fork 0
Migration Guide
A practical upgrade guide for teams moving from older RBXStateMachine snippets and docs to the current FSM/Orchestrator runtime.
Important
This page focuses on the migration issues most likely to affect real projects using older wiki examples: bootstrap path changes, auto-registration assumptions, FSM auto-start, scheduler startup, testing paths, and entity mutability.
If your project was built from older examples, these are the first things to verify.
| Older assumption | Current runtime |
|---|---|
framework is ReplicatedStorage.RBXStateMachine
|
repo default maps to ReplicatedStorage.Orchestrator
|
| scheduler is separate/manual | scheduler is started during RegisterComponents()
|
CreateStateMachine() returns idle machine by default |
auto-start is now the default unless AutoStart = false
|
tests are under FSM/Tests
|
real automated suite is under FSM/Orchestrator/ServiceManager/Tests
|
| entity/FSM folders must be one exact path | factory scans all descendants for alias-named folders |
any entity with ApplyChanges can always commit |
UpdateEntity() requires Mutable = true
|
Old snippets often look like this:
local FSM = require(game:GetService("ReplicatedStorage").RBXStateMachine)
FSM.Orchestrator:RegisterComponents()Current repo-aligned bootstrap should look like this:
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Orchestrator = require(ReplicatedStorage:WaitForChild("Orchestrator"))
Orchestrator:RegisterComponents()If your Rojo project still intentionally exposes a different module name, that is fineβbut this repository's own source-of-truth mapping is ReplicatedStorage.Orchestrator.
Older guidance often treated the scheduler as optional manual setup. In the current Orchestrator bootstrap:
- scheduler is initialized
-
Orchestrator.Scheduler:Start()is called - the global FSM heartbeat task is scheduled
So code like this is usually redundant in normal usage:
Orchestrator.Scheduler:Start()Older gameplay code often did:
local job = Orchestrator.CreateStateMachine({...})
job:Start({ State = "Validate" })In the current factory, CreateStateMachine() auto-starts unless you explicitly pass:
AutoStart = false- you intentionally disabled auto-start
- you created the machine outside the usual factory flow
- you need strict delayed orchestration after construction
Older docs often implied only one hard-coded folder path. The current factory scans all descendants for these alias names:
EntityEntities
StateMachineStateMachinesSMFSM
Even though discovery is more flexible now, standardize on:
ReplicatedStorage/Entity
ReplicatedStorage/StateMachine
unless you have a strong architectural reason to do otherwise.
This is one of the most important upgrade checks.
If an entity ever does:
self:UpdateEntity()then declare:
Mutable = trueOlder example patterns may appear to work conceptually but now fail fast at commit time on immutable entities.
Search for entities that:
- define
Open,Close,Reset,Damage,Heal, or similar mutating methods - call
UpdateEntity()directly - stage schema values before committing
Then confirm each one explicitly opts into mutability.
If your older code uses task.delay() or hand-rolled timers inside states, prefer the current native timing model:
- fixed delayed exit β
ScheduleTransition() - state-owned deadline β
Timeout+OnTimeout - reactive branching β
Transitions[].Condition - delayed self-loop/polling β
WaitSpan
Old style:
self:AddState("Idle", function(fsm)
task.delay(2, function()
if fsm.State == "Idle" then
fsm.State = "Spin"
end
end)
end)Better current style:
self:AddState("Idle", function(fsm)
fsm:ScheduleTransition(2, "Spin")
end, { "Spin" })Older docs often stop at logs. The current runtime has a much richer debugging surface through ServiceManager.
Current root tabs:
TASKSFSMENTITYNETWORKDATASTOREINSIGHTSCONSOLELOGSPROFILER
Migration recommendation:
- keep log-based debugging for failures
- add ServiceManager-driven inspection for state, replication, and performance issues
- use
servercontext when debugging authoritative problems
Older text may mention FSM/Tests as the main suite location.
Current automated test source of truth is:
FSM/Orchestrator/ServiceManager/Tests
with:
TestRunner.luauRunAllTests.luauSpecs/*.spec.luau
The repo currently contains 18 spec files there.
- require path updated to
ReplicatedStorage.Orchestrator - both server and client call
RegisterComponents() - no redundant manual scheduler startup in normal boot flow
- entity and FSM folders use supported alias names
- modules return table definitions
- entity definitions that commit changes declare
Mutable = true
- manual
:Start()calls reviewed for redundancy - timing patterns modernized to
ScheduleTransition/Timeout/Condition - duplicate ID assumptions removed
- ServiceManager started only in development/staging contexts
- test references updated to
ServiceManager/Tests - profiling workflow uses
TASKS,PROFILER, andINSIGHTS
A low-risk order for upgrading an existing game:
- update the framework require path
- confirm registration folders are discoverable
- audit mutable entities
- remove redundant manual starts only after verifying auto-start expectations
- modernize timer patterns
- validate replication in Studio with ServiceManager
- run automated specs / smoke tests before shipping
Quick Links: Home Β· Quick Start Β· API Reference Β· Architecture Β· Examples Β· Glossary
Copyright: Β© 2026 RBXStateMachine contributors Β· Repository Β· License information