Examples
Runnable programs live in the engine repo under examples/, and the package's testable Example functions double as documentation on pkg.go.dev.
You can open any of these live in the studio.
Counter — context that mutates
One state, context updated on each event. The smallest useful machine.
go
m, _ := fate.CreateMachine(fate.MachineConfig[Ctx, Evt]{
ID: "counter", Initial: "active",
States: map[string]fate.StateNodeConfig[Ctx, Evt]{
"active": {On: map[string][]fate.TransitionConfig[Ctx, Evt]{
"Inc": {{Actions: []fate.Action[Ctx, Evt]{fate.Assign(func(c Ctx, _ Evt) Ctx { c.Count++; return c })}}},
"Reset": {{Target: "active", Actions: []fate.Action[Ctx, Evt]{fate.Assign(func(c Ctx, _ Evt) Ctx { c.Count = 0; return c })}}},
}},
},
})Full source: examples/quickstart.
Traffic light — compound (hierarchical) states
red → green → yellow → red, with a pedestrian walk sub-state nested inside red. The NEXT transition is declared once on the parent red and applies whichever child is active.
go
m, _ := fate.CreateMachine(fate.MachineConfig[struct{}, string]{
ID: "traffic", Initial: "red",
States: map[string]fate.StateNodeConfig[struct{}, string]{
"red": {
Initial: "stop",
States: map[string]fate.StateNodeConfig[struct{}, string]{
"stop": {On: map[string][]fate.TransitionConfig[struct{}, string]{"WALK": {{Target: "walk"}}}},
"walk": {On: map[string][]fate.TransitionConfig[struct{}, string]{"WAIT": {{Target: "stop"}}}},
},
On: map[string][]fate.TransitionConfig[struct{}, string]{"NEXT": {{Target: "green"}}},
},
"green": {On: map[string][]fate.TransitionConfig[struct{}, string]{"NEXT": {{Target: "yellow"}}}},
"yellow": {On: map[string][]fate.TransitionConfig[struct{}, string]{"NEXT": {{Target: "red"}}}},
},
})
a := fate.NewActor(m)
_ = a.Start(context.Background())
fmt.Println(a.Snapshot().Value.Path()) // red.stopThen render it:
go
fmt.Println(fate.RenderMermaid(m.Describe(), fate.MermaidOptions{}))Full source: examples/trafficlight.
Real-time timer — delayed (after) transitions
A machine with an after transition, driven by a real-time adapter that reads PendingTimers() and calls FireTimer(...) when the OS timer elapses — the engine itself never touches the clock.
Full source: examples/realtime-timer.
Feature matrix
| Want to see… | Look at |
|---|---|
Context mutation with Assign | quickstart |
| Compound / hierarchical states | trafficlight |
Delayed after transitions + an adapter | realtime-timer |
| Parallel regions, history, guards, invoked actors | pkg.go.dev examples |
Next
- How it works — the engine/adapter split behind the timer example.
- Concepts — the API names for each feature above.